summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Library/ArmLib/Arm
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Library/ArmLib/Arm')
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S166
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmLibSupport.asm169
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S95
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm99
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimer.c167
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S98
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.asm99
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c70
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h40
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Support.S305
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Support.asm298
11 files changed, 1606 insertions, 0 deletions
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S
new file mode 100644
index 0000000000..a0b5ed5002
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S
@@ -0,0 +1,166 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011 - 2016, ARM Limited. All rights reserved.
+# Copyright (c) 2016, Linaro 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 <AsmMacroIoLib.h>
+
+ASM_FUNC(ArmReadMidr)
+ mrc p15,0,R0,c0,c0,0
+ bx LR
+
+ASM_FUNC(ArmCacheInfo)
+ mrc p15,0,R0,c0,c0,1
+ bx LR
+
+ASM_FUNC(ArmGetInterruptState)
+ mrs R0,CPSR
+ tst R0,#0x80 @Check if IRQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ASM_FUNC(ArmGetFiqState)
+ mrs R0,CPSR
+ tst R0,#0x40 @Check if FIQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ASM_FUNC(ArmSetDomainAccessControl)
+ mcr p15,0,r0,c3,c0,0
+ bx lr
+
+ASM_FUNC(CPSRMaskInsert) @ on entry, r0 is the mask and r1 is the field to insert
+ stmfd sp!, {r4-r12, lr} @ save all the banked registers
+ mov r3, sp @ copy the stack pointer into a non-banked register
+ mrs r2, cpsr @ read the cpsr
+ bic r2, r2, r0 @ clear mask in the cpsr
+ and r1, r1, r0 @ clear bits outside the mask in the input
+ orr r2, r2, r1 @ set field
+ msr cpsr_cxsf, r2 @ write back cpsr (may have caused a mode switch)
+ isb
+ mov sp, r3 @ restore stack pointer
+ ldmfd sp!, {r4-r12, lr} @ restore registers
+ bx lr @ return (hopefully thumb-safe!)
+
+ASM_FUNC(CPSRRead)
+ mrs r0, cpsr
+ bx lr
+
+ASM_FUNC(ArmReadCpacr)
+ mrc p15, 0, r0, c1, c0, 2
+ bx lr
+
+ASM_FUNC(ArmWriteCpacr)
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ bx lr
+
+ASM_FUNC(ArmWriteAuxCr)
+ mcr p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_FUNC(ArmReadAuxCr)
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_FUNC(ArmSetTTBR0)
+ mcr p15,0,r0,c2,c0,0
+ isb
+ bx lr
+
+ASM_FUNC(ArmSetTTBCR)
+ mcr p15, 0, r0, c2, c0, 2
+ isb
+ bx lr
+
+ASM_FUNC(ArmGetTTBR0BaseAddress)
+ mrc p15,0,r0,c2,c0,0
+ MOV32 (r1, 0xFFFFC000)
+ and r0, r0, r1
+ isb
+ bx lr
+
+//
+//VOID
+//ArmUpdateTranslationTableEntry (
+// IN VOID *TranslationTableEntry // R0
+// IN VOID *MVA // R1
+// );
+ASM_FUNC(ArmUpdateTranslationTableEntry)
+ mcr p15,0,R0,c7,c14,1 @ DCCIMVAC Clean data cache by MVA
+ dsb
+ mcr p15,0,R1,c8,c7,1 @ TLBIMVA TLB Invalidate MVA
+ mcr p15,0,R9,c7,c5,6 @ BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ASM_FUNC(ArmInvalidateTlb)
+ mov r0,#0
+ mcr p15,0,r0,c8,c7,0
+ mcr p15,0,R9,c7,c5,6 @ BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ASM_FUNC(ArmReadScr)
+ mrc p15, 0, r0, c1, c1, 0
+ bx lr
+
+ASM_FUNC(ArmWriteScr)
+ mcr p15, 0, r0, c1, c1, 0
+ isb
+ bx lr
+
+ASM_FUNC(ArmReadHVBar)
+ mrc p15, 4, r0, c12, c0, 0
+ bx lr
+
+ASM_FUNC(ArmWriteHVBar)
+ mcr p15, 4, r0, c12, c0, 0
+ bx lr
+
+ASM_FUNC(ArmReadMVBar)
+ mrc p15, 0, r0, c12, c0, 1
+ bx lr
+
+ASM_FUNC(ArmWriteMVBar)
+ mcr p15, 0, r0, c12, c0, 1
+ bx lr
+
+ASM_FUNC(ArmCallWFE)
+ wfe
+ bx lr
+
+ASM_FUNC(ArmCallSEV)
+ sev
+ bx lr
+
+ASM_FUNC(ArmReadSctlr)
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bx lr
+
+ASM_FUNC(ArmReadCpuActlr)
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_FUNC(ArmWriteCpuActlr)
+ mcr p15, 0, r0, c1, c0, 1
+ dsb
+ isb
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.asm
new file mode 100644
index 0000000000..85b0feee20
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.asm
@@ -0,0 +1,169 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+// Copyright (c) 2011 - 2016, 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 AsmMacroIoLib.inc
+
+
+ INCLUDE AsmMacroExport.inc
+
+ RVCT_ASM_EXPORT ArmReadMidr
+ mrc p15,0,R0,c0,c0,0
+ bx LR
+
+ RVCT_ASM_EXPORT ArmCacheInfo
+ mrc p15,0,R0,c0,c0,1
+ bx LR
+
+ RVCT_ASM_EXPORT ArmGetInterruptState
+ mrs R0,CPSR
+ tst R0,#0x80 // Check if IRQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ RVCT_ASM_EXPORT ArmGetFiqState
+ mrs R0,CPSR
+ tst R0,#0x40 // Check if FIQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ RVCT_ASM_EXPORT ArmSetDomainAccessControl
+ mcr p15,0,r0,c3,c0,0
+ bx lr
+
+ RVCT_ASM_EXPORT CPSRMaskInsert
+ stmfd sp!, {r4-r12, lr} // save all the banked registers
+ mov r3, sp // copy the stack pointer into a non-banked register
+ mrs r2, cpsr // read the cpsr
+ bic r2, r2, r0 // clear mask in the cpsr
+ and r1, r1, r0 // clear bits outside the mask in the input
+ orr r2, r2, r1 // set field
+ msr cpsr_cxsf, r2 // write back cpsr (may have caused a mode switch)
+ isb
+ mov sp, r3 // restore stack pointer
+ ldmfd sp!, {r4-r12, lr} // restore registers
+ bx lr // return (hopefully thumb-safe!) // return (hopefully thumb-safe!)
+
+ RVCT_ASM_EXPORT CPSRRead
+ mrs r0, cpsr
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCpacr
+ mrc p15, 0, r0, c1, c0, 2
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCpacr
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteAuxCr
+ mcr p15, 0, r0, c1, c0, 1
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadAuxCr
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ RVCT_ASM_EXPORT ArmSetTTBR0
+ mcr p15,0,r0,c2,c0,0
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmSetTTBCR
+ mcr p15, 0, r0, c2, c0, 2
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmGetTTBR0BaseAddress
+ mrc p15,0,r0,c2,c0,0
+ MOV32 r1, 0xFFFFC000
+ and r0, r0, r1
+ isb
+ bx lr
+
+//
+//VOID
+//ArmUpdateTranslationTableEntry (
+// IN VOID *TranslationTableEntry // R0
+// IN VOID *MVA // R1
+// );
+ RVCT_ASM_EXPORT ArmUpdateTranslationTableEntry
+ mcr p15,0,R0,c7,c14,1 // DCCIMVAC Clean data cache by MVA
+ dsb
+ mcr p15,0,R1,c8,c7,1 // TLBIMVA TLB Invalidate MVA
+ mcr p15,0,R9,c7,c5,6 // BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmInvalidateTlb
+ mov r0,#0
+ mcr p15,0,r0,c8,c7,0
+ mcr p15,0,R9,c7,c5,6 // BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadScr
+ mrc p15, 0, r0, c1, c1, 0
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteScr
+ mcr p15, 0, r0, c1, c1, 0
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadHVBar
+ mrc p15, 4, r0, c12, c0, 0
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteHVBar
+ mcr p15, 4, r0, c12, c0, 0
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadMVBar
+ mrc p15, 0, r0, c12, c0, 1
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteMVBar
+ mcr p15, 0, r0, c12, c0, 1
+ bx lr
+
+ RVCT_ASM_EXPORT ArmCallWFE
+ wfe
+ bx lr
+
+ RVCT_ASM_EXPORT ArmCallSEV
+ sev
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadSctlr
+ mrc p15, 0, r0, c1, c0, 0 // Read SCTLR into R0 (Read control register configuration data)
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmReadCpuActlr
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCpuActlr
+ mcr p15, 0, r0, c1, c0, 1
+ dsb
+ isb
+ bx lr
+
+ END
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
new file mode 100644
index 0000000000..3939bbc6b6
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
@@ -0,0 +1,95 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+# Copyright (c) 2016, Linaro 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 <AsmMacroIoLib.h>
+
+ASM_FUNC(ArmIsMpCore)
+ mrc p15,0,R0,c0,c0,5
+ // Get Multiprocessing extension (bit31) & U bit (bit30)
+ and R0, R0, #0xC0000000
+ // if (bit31 == 1) && (bit30 == 0) then the processor is part of a multiprocessor system
+ cmp R0, #0x80000000
+ moveq R0, #1
+ movne R0, #0
+ bx LR
+
+ASM_FUNC(ArmEnableAsynchronousAbort)
+ cpsie a
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableAsynchronousAbort)
+ cpsid a
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableIrq)
+ cpsie i
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableIrq)
+ cpsid i
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableFiq)
+ cpsie f
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableFiq)
+ cpsid f
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableInterrupts)
+ cpsie if
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableInterrupts)
+ cpsid if
+ isb
+ bx LR
+
+// UINT32
+// ReadCCSIDR (
+// IN UINT32 CSSELR
+// )
+ASM_FUNC(ReadCCSIDR)
+ mcr p15,2,r0,c0,c0,0 @ Write Cache Size Selection Register (CSSELR)
+ isb
+ mrc p15,1,r0,c0,c0,0 @ Read current CP15 Cache Size ID Register (CCSIDR)
+ bx lr
+
+// UINT32
+// ReadCLIDR (
+// IN UINT32 CSSELR
+// )
+ASM_FUNC(ReadCLIDR)
+ mrc p15,1,r0,c0,c0,1 @ Read CP15 Cache Level ID Register
+ bx lr
+
+ASM_FUNC(ArmReadNsacr)
+ mrc p15, 0, r0, c1, c1, 2
+ bx lr
+
+ASM_FUNC(ArmWriteNsacr)
+ mcr p15, 0, r0, c1, c1, 2
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
new file mode 100644
index 0000000000..cac39e36a5
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
@@ -0,0 +1,99 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+// 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 AsmMacroExport.inc
+
+
+//------------------------------------------------------------------------------
+
+ RVCT_ASM_EXPORT ArmIsMpCore
+ mrc p15,0,R0,c0,c0,5
+ // Get Multiprocessing extension (bit31) & U bit (bit30)
+ and R0, R0, #0xC0000000
+ // if (bit31 == 1) && (bit30 == 0) then the processor is part of a multiprocessor system
+ cmp R0, #0x80000000
+ moveq R0, #1
+ movne R0, #0
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableAsynchronousAbort
+ cpsie a
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableAsynchronousAbort
+ cpsid a
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableIrq
+ cpsie i
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableIrq
+ cpsid i
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableFiq
+ cpsie f
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableFiq
+ cpsid f
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableInterrupts
+ cpsie if
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableInterrupts
+ cpsid if
+ isb
+ bx LR
+
+// UINT32
+// ReadCCSIDR (
+// IN UINT32 CSSELR
+// )
+ RVCT_ASM_EXPORT ReadCCSIDR
+ mcr p15,2,r0,c0,c0,0 ; Write Cache Size Selection Register (CSSELR)
+ isb
+ mrc p15,1,r0,c0,c0,0 ; Read current CP15 Cache Size ID Register (CCSIDR)
+ bx lr
+
+// UINT32
+// ReadCLIDR (
+// IN UINT32 CSSELR
+// )
+ RVCT_ASM_EXPORT ReadCLIDR
+ mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadNsacr
+ mrc p15, 0, r0, c1, c1, 2
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteNsacr
+ mcr p15, 0, r0, c1, c1, 2
+ bx lr
+
+ END
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimer.c b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimer.c
new file mode 100644
index 0000000000..c0b3a9ed5d
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimer.c
@@ -0,0 +1,167 @@
+/** @file
+*
+* Copyright (c) 2011 - 2014, 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/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include "ArmV7Lib.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 ();
+ return;
+
+ case CntPct:
+ *((UINT64 *)DstBuf) = ArmReadCntPct ();
+ return;
+
+ case CntkCtl:
+ *((UINTN *)DstBuf) = ArmReadCntkCtl();
+ return;
+
+ case CntpTval:
+ *((UINTN *)DstBuf) = ArmReadCntpTval ();
+ return;
+
+ case CntpCtl:
+ *((UINTN *)DstBuf) = ArmReadCntpCtl ();
+ return;
+
+ case CntvTval:
+ *((UINTN *)DstBuf) = ArmReadCntvTval ();
+ return;
+
+ case CntvCtl:
+ *((UINTN *)DstBuf) = ArmReadCntvCtl ();
+ return;
+
+ case CntvCt:
+ *((UINT64 *)DstBuf) = ArmReadCntvCt ();
+ return;
+
+ case CntpCval:
+ *((UINT64 *)DstBuf) = ArmReadCntpCval ();
+ return;
+
+ case CntvCval:
+ *((UINT64 *)DstBuf) = ArmReadCntvCval ();
+ return;
+
+ case CntvOff:
+ *((UINT64 *)DstBuf) = ArmReadCntvOff ();
+ return;
+
+ 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);
+ }
+
+ *((UINT64 *)DstBuf) = 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);
+ }
+}
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S
new file mode 100644
index 0000000000..9a7794f0ad
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S
@@ -0,0 +1,98 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2011, ARM Limited. All rights reserved.
+# Copyright (c) 2016, Linaro 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 <AsmMacroIoLib.h>
+
+ASM_FUNC(ArmReadCntFrq)
+ mrc p15, 0, r0, c14, c0, 0 @ Read CNTFRQ
+ bx lr
+
+ASM_FUNC(ArmWriteCntFrq)
+ mcr p15, 0, r0, c14, c0, 0 @ Write to CNTFRQ
+ bx lr
+
+ASM_FUNC(ArmReadCntPct)
+ mrrc p15, 0, r0, r1, c14 @ Read CNTPT (Physical counter register)
+ bx lr
+
+ASM_FUNC(ArmReadCntkCtl)
+ mrc p15, 0, r0, c14, c1, 0 @ Read CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntkCtl)
+ mcr p15, 0, r0, c14, c1, 0 @ Write to CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ASM_FUNC(ArmReadCntpTval)
+ mrc p15, 0, r0, c14, c2, 0 @ Read CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntpTval)
+ mcr p15, 0, r0, c14, c2, 0 @ Write to CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ASM_FUNC(ArmReadCntpCtl)
+ mrc p15, 0, r0, c14, c2, 1 @ Read CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntpCtl)
+ mcr p15, 0, r0, c14, c2, 1 @ Write to CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ASM_FUNC(ArmReadCntvTval)
+ mrc p15, 0, r0, c14, c3, 0 @ Read CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntvTval)
+ mcr p15, 0, r0, c14, c3, 0 @ Write to CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ASM_FUNC(ArmReadCntvCtl)
+ mrc p15, 0, r0, c14, c3, 1 @ Read CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntvCtl)
+ mcr p15, 0, r0, c14, c3, 1 @ Write to CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ASM_FUNC(ArmReadCntvCt)
+ mrrc p15, 1, r0, r1, c14 @ Read CNTVCT (Virtual Count Register)
+ bx lr
+
+ASM_FUNC(ArmReadCntpCval)
+ mrrc p15, 2, r0, r1, c14 @ Read CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntpCval)
+ mcrr p15, 2, r0, r1, c14 @ Write to CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ASM_FUNC(ArmReadCntvCval)
+ mrrc p15, 3, r0, r1, c14 @ Read CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntvCval)
+ mcrr p15, 3, r0, r1, c14 @ write to CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ASM_FUNC(ArmReadCntvOff)
+ mrrc p15, 4, r0, r1, c14 @ Read CNTVOFF (virtual Offset register)
+ bx lr
+
+ASM_FUNC(ArmWriteCntvOff)
+ mcrr p15, 4, r0, r1, c14 @ Write to CNTVOFF (Virtual Offset register)
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.asm b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.asm
new file mode 100644
index 0000000000..a53dd60457
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.asm
@@ -0,0 +1,99 @@
+//------------------------------------------------------------------------------
+//
+// 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 AsmMacroExport.inc
+ PRESERVE8
+
+ RVCT_ASM_EXPORT ArmReadCntFrq
+ mrc p15, 0, r0, c14, c0, 0 ; Read CNTFRQ
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntFrq
+ mcr p15, 0, r0, c14, c0, 0 ; Write to CNTFRQ
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntPct
+ mrrc p15, 0, r0, r1, c14 ; Read CNTPT (Physical counter register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntkCtl
+ mrc p15, 0, r0, c14, c1, 0 ; Read CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntkCtl
+ mcr p15, 0, r0, c14, c1, 0 ; Write to CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntpTval
+ mrc p15, 0, r0, c14, c2, 0 ; Read CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntpTval
+ mcr p15, 0, r0, c14, c2, 0 ; Write to CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntpCtl
+ mrc p15, 0, r0, c14, c2, 1 ; Read CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntpCtl
+ mcr p15, 0, r0, c14, c2, 1 ; Write to CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntvTval
+ mrc p15, 0, r0, c14, c3, 0 ; Read CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntvTval
+ mcr p15, 0, r0, c14, c3, 0 ; Write to CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntvCtl
+ mrc p15, 0, r0, c14, c3, 1 ; Read CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntvCtl
+ mcr p15, 0, r0, c14, c3, 1 ; Write to CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntvCt
+ mrrc p15, 1, r0, r1, c14 ; Read CNTVCT (Virtual Count Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntpCval
+ mrrc p15, 2, r0, r1, c14 ; Read CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntpCval
+ mcrr p15, 2, r0, r1, c14 ; Write to CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntvCval
+ mrrc p15, 3, r0, r1, c14 ; Read CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntvCval
+ mcrr p15, 3, r0, r1, c14 ; write to CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadCntvOff
+ mrrc p15, 4, r0, r1, c14 ; Read CNTVOFF (virtual Offset register)
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteCntvOff
+ mcrr p15, 4, r0, r1, c14 ; Write to CNTVOFF (Virtual Offset register)
+ bx lr
+
+ END
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
new file mode 100644
index 0000000000..23a7f2f2bb
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
@@ -0,0 +1,70 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, 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/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include "ArmV7Lib.h"
+#include "ArmLibPrivate.h"
+
+VOID
+ArmV7DataCacheOperation (
+ IN ARM_V7_CACHE_OPERATION DataCacheOperation
+ )
+{
+ UINTN SavedInterruptState;
+
+ SavedInterruptState = ArmGetInterruptState ();
+ ArmDisableInterrupts ();
+
+ ArmV7AllDataCachesOperation (DataCacheOperation);
+
+ ArmDataSynchronizationBarrier ();
+
+ if (SavedInterruptState) {
+ ArmEnableInterrupts ();
+ }
+}
+
+VOID
+EFIAPI
+ArmInvalidateDataCache (
+ VOID
+ )
+{
+ ArmDataSynchronizationBarrier ();
+ ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+ VOID
+ )
+{
+ ArmDataSynchronizationBarrier ();
+ ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+ VOID
+ )
+{
+ ArmDataSynchronizationBarrier ();
+ ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
+}
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h
new file mode 100644
index 0000000000..e4595c44fd
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h
@@ -0,0 +1,40 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+
+#ifndef __ARM_V7_LIB_H__
+#define __ARM_V7_LIB_H__
+
+#define ID_MMFR0_SHARELVL_SHIFT 12
+#define ID_MMFR0_SHARELVL_MASK 0xf
+#define ID_MMFR0_SHARELVL_ONE 0
+#define ID_MMFR0_SHARELVL_TWO 1
+
+#define ID_MMFR0_INNERSHR_SHIFT 28
+#define ID_MMFR0_INNERSHR_MASK 0xf
+#define ID_MMFR0_OUTERSHR_SHIFT 8
+#define ID_MMFR0_OUTERSHR_MASK 0xf
+
+#define ID_MMFR0_SHR_IMP_UNCACHED 0
+#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
+#define ID_MMFR0_SHR_IGNORED 0xf
+
+typedef VOID (*ARM_V7_CACHE_OPERATION)(UINT32);
+
+VOID
+ArmV7AllDataCachesOperation (
+ IN ARM_V7_CACHE_OPERATION DataCacheOperation
+ );
+
+#endif // __ARM_V7_LIB_H__
+
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S
new file mode 100644
index 0000000000..281499b46c
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S
@@ -0,0 +1,305 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
+# Copyright (c) 2016, Linaro 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 <AsmMacroIoLib.h>
+
+.set DC_ON, (0x1<<2)
+.set IC_ON, (0x1<<12)
+.set CTRL_M_BIT, (1 << 0)
+.set CTRL_C_BIT, (1 << 2)
+.set CTRL_B_BIT, (1 << 7)
+.set CTRL_I_BIT, (1 << 12)
+
+
+ASM_FUNC(ArmInvalidateDataCacheEntryByMVA)
+ mcr p15, 0, r0, c7, c6, 1 @invalidate single data cache line
+ bx lr
+
+ASM_FUNC(ArmCleanDataCacheEntryByMVA)
+ mcr p15, 0, r0, c7, c10, 1 @clean single data cache line
+ bx lr
+
+
+ASM_FUNC(ArmCleanDataCacheEntryToPoUByMVA)
+ mcr p15, 0, r0, c7, c11, 1 @clean single data cache line to PoU
+ bx lr
+
+ASM_FUNC(ArmInvalidateInstructionCacheEntryToPoUByMVA)
+ mcr p15, 0, r0, c7, c5, 1 @Invalidate single instruction cache line to PoU
+ mcr p15, 0, r0, c7, c5, 7 @Invalidate branch predictor
+ bx lr
+
+ASM_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
+ mcr p15, 0, r0, c7, c14, 1 @clean and invalidate single data cache line
+ bx lr
+
+
+ASM_FUNC(ArmInvalidateDataCacheEntryBySetWay)
+ mcr p15, 0, r0, c7, c6, 2 @ Invalidate this line
+ bx lr
+
+
+ASM_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay)
+ mcr p15, 0, r0, c7, c14, 2 @ Clean and Invalidate this line
+ bx lr
+
+
+ASM_FUNC(ArmCleanDataCacheEntryBySetWay)
+ mcr p15, 0, r0, c7, c10, 2 @ Clean this line
+ bx lr
+
+ASM_FUNC(ArmInvalidateInstructionCache)
+ mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableMmu)
+ mrc p15,0,R0,c1,c0,0
+ orr R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ dsb
+ isb
+ bx LR
+
+
+ASM_FUNC(ArmDisableMmu)
+ mrc p15,0,R0,c1,c0,0
+ bic R0,R0,#1
+ mcr p15,0,R0,c1,c0,0 @Disable MMU
+
+ mcr p15,0,R0,c8,c7,0 @Invalidate TLB
+ mcr p15,0,R0,c7,c5,6 @Invalidate Branch predictor array
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableCachesAndMmu)
+ mrc p15, 0, r0, c1, c0, 0 @ Get control register
+ bic r0, r0, #CTRL_M_BIT @ Disable MMU
+ bic r0, r0, #CTRL_C_BIT @ Disable D Cache
+ bic r0, r0, #CTRL_I_BIT @ Disable I Cache
+ mcr p15, 0, r0, c1, c0, 0 @ Write control register
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmMmuEnabled)
+ mrc p15,0,R0,c1,c0,0
+ and R0,R0,#1
+ bx LR
+
+ASM_FUNC(ArmEnableDataCache)
+ ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableDataCache)
+ ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableInstructionCache)
+ ldr R1,=IC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set I bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableInstructionCache)
+ ldr R1,=IC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear I bit.
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableSWPInstruction)
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000400
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+ bx LR
+
+ASM_FUNC(ArmEnableBranchPrediction)
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmDisableBranchPrediction)
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ dsb
+ isb
+ bx LR
+
+ASM_FUNC(ArmSetLowVectors)
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 @ clear V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ASM_FUNC(ArmSetHighVectors)
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00002000 @ Set V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ASM_FUNC(ArmV7AllDataCachesOperation)
+ stmfd SP!,{r4-r12, LR}
+ mov R1, R0 @ Save Function call in R1
+ mrc p15, 1, R6, c0, c0, 1 @ Read CLIDR
+ ands R3, R6, #0x7000000 @ Mask out all but Level of Coherency (LoC)
+ mov R3, R3, LSR #23 @ Cache level value (naturally aligned)
+ beq L_Finished
+ mov R10, #0
+
+Loop1:
+ add R2, R10, R10, LSR #1 @ Work out 3xcachelevel
+ mov R12, R6, LSR R2 @ bottom 3 bits are the Cache type for this level
+ and R12, R12, #7 @ get those 3 bits alone
+ cmp R12, #2
+ blt L_Skip @ no cache or only instruction cache at this level
+ mcr p15, 2, R10, c0, c0, 0 @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
+ isb @ isb to sync the change to the CacheSizeID reg
+ mrc p15, 1, R12, c0, c0, 0 @ reads current Cache Size ID register (CCSIDR)
+ and R2, R12, #0x7 @ extract the line length field
+ add R2, R2, #4 @ add 4 for the line length offset (log2 16 bytes)
+@ ldr R4, =0x3FF
+ mov R4, #0x400
+ sub R4, R4, #1
+ ands R4, R4, R12, LSR #3 @ R4 is the max number on the way size (right aligned)
+ clz R5, R4 @ R5 is the bit position of the way size increment
+@ ldr R7, =0x00007FFF
+ mov R7, #0x00008000
+ sub R7, R7, #1
+ ands R7, R7, R12, LSR #13 @ R7 is the max number of the index size (right aligned)
+
+Loop2:
+ mov R9, R4 @ R9 working copy of the max way size (right aligned)
+
+Loop3:
+ orr R0, R10, R9, LSL R5 @ factor in the way number and cache number into R11
+ orr R0, R0, R7, LSL R2 @ factor in the index number
+
+ blx R1
+
+ subs R9, R9, #1 @ decrement the way number
+ bge Loop3
+ subs R7, R7, #1 @ decrement the index
+ bge Loop2
+L_Skip:
+ add R10, R10, #2 @ increment the cache number
+ cmp R3, R10
+ bgt Loop1
+
+L_Finished:
+ dsb
+ ldmfd SP!, {r4-r12, lr}
+ bx LR
+
+ASM_FUNC(ArmDataMemoryBarrier)
+ dmb
+ bx LR
+
+ASM_FUNC(ArmDataSynchronizationBarrier)
+ dsb
+ bx LR
+
+ASM_FUNC(ArmInstructionSynchronizationBarrier)
+ isb
+ bx LR
+
+ASM_FUNC(ArmReadVBar)
+ # Set the Address of the Vector Table in the VBAR register
+ mrc p15, 0, r0, c12, c0, 0
+ bx lr
+
+ASM_FUNC(ArmWriteVBar)
+ # Set the Address of the Vector Table in the VBAR register
+ mcr p15, 0, r0, c12, c0, 0
+ # Ensure the SCTLR.V bit is clear
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 @ clear V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx lr
+
+ASM_FUNC(ArmEnableVFP)
+ # Read CPACR (Coprocessor Access Control Register)
+ mrc p15, 0, r0, c1, c0, 2
+ # Enable VPF access (Full Access to CP10, CP11) (V* instructions)
+ orr r0, r0, #0x00f00000
+ # Write back CPACR (Coprocessor Access Control Register)
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ # Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.
+ mov r0, #0x40000000
+#ifndef __clang__
+ mcr p10,#0x7,r0,c8,c0,#0
+#else
+ vmsr fpexc, r0
+#endif
+ bx lr
+
+ASM_FUNC(ArmCallWFI)
+ wfi
+ bx lr
+
+#Note: Return 0 in Uniprocessor implementation
+ASM_FUNC(ArmReadCbar)
+ mrc p15, 4, r0, c15, c0, 0 @ Read Configuration Base Address Register
+ bx lr
+
+ASM_FUNC(ArmReadMpidr)
+ mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
+ bx lr
+
+ASM_FUNC(ArmReadTpidrurw)
+ mrc p15, 0, r0, c13, c0, 2 @ read TPIDRURW
+ bx lr
+
+ASM_FUNC(ArmWriteTpidrurw)
+ mcr p15, 0, r0, c13, c0, 2 @ write TPIDRURW
+ bx lr
+
+ASM_FUNC(ArmIsArchTimerImplemented)
+ mrc p15, 0, r0, c0, c1, 1 @ Read ID_PFR1
+ and r0, r0, #0x000F0000
+ bx lr
+
+ASM_FUNC(ArmReadIdPfr1)
+ mrc p15, 0, r0, c0, c1, 1 @ Read ID_PFR1 Register
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.asm b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.asm
new file mode 100644
index 0000000000..342d8970dc
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.asm
@@ -0,0 +1,298 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+// Copyright (c) 2011 - 2014, 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 AsmMacroExport.inc
+ PRESERVE8
+
+DC_ON EQU ( 0x1:SHL:2 )
+IC_ON EQU ( 0x1:SHL:12 )
+CTRL_M_BIT EQU (1 << 0)
+CTRL_C_BIT EQU (1 << 2)
+CTRL_B_BIT EQU (1 << 7)
+CTRL_I_BIT EQU (1 << 12)
+
+
+ RVCT_ASM_EXPORT ArmInvalidateDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c6, 1 ; invalidate single data cache line
+ bx lr
+
+ RVCT_ASM_EXPORT ArmCleanDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c10, 1 ; clean single data cache line
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmInvalidateInstructionCacheEntryToPoUByMVA
+ mcr p15, 0, r0, c7, c5, 1 ; invalidate single instruction cache line to PoU
+ mcr p15, 0, r0, c7, c5, 7 ; invalidate branch predictor
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmCleanDataCacheEntryToPoUByMVA
+ mcr p15, 0, r0, c7, c11, 1 ; clean single data cache line to PoU
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmCleanInvalidateDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c14, 1 ; clean and invalidate single data cache line
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmInvalidateDataCacheEntryBySetWay
+ mcr p15, 0, r0, c7, c6, 2 ; Invalidate this line
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmCleanInvalidateDataCacheEntryBySetWay
+ mcr p15, 0, r0, c7, c14, 2 ; Clean and Invalidate this line
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmCleanDataCacheEntryBySetWay
+ mcr p15, 0, r0, c7, c10, 2 ; Clean this line
+ bx lr
+
+
+ RVCT_ASM_EXPORT ArmInvalidateInstructionCache
+ mcr p15,0,R0,c7,c5,0 ;Invalidate entire instruction cache
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableMmu
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr R0,R0,#1 ; Set SCTLR.M bit : Enable MMU
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableMmu
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic R0,R0,#1 ; Clear SCTLR.M bit : Disable MMU
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+
+ mcr p15,0,R0,c8,c7,0 ; TLBIALL : Invalidate unified TLB
+ mcr p15,0,R0,c7,c5,6 ; BPIALL : Invalidate entire branch predictor array
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableCachesAndMmu
+ mrc p15, 0, r0, c1, c0, 0 ; Get control register
+ bic r0, r0, #CTRL_M_BIT ; Disable MMU
+ bic r0, r0, #CTRL_C_BIT ; Disable D Cache
+ bic r0, r0, #CTRL_I_BIT ; Disable I Cache
+ mcr p15, 0, r0, c1, c0, 0 ; Write control register
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmMmuEnabled
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ and R0,R0,#1
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableDataCache
+ ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr R0,R0,R1 ; Set SCTLR.C bit : Data and unified caches enabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableDataCache
+ ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic R0,R0,R1 ; Clear SCTLR.C bit : Data and unified caches disabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableInstructionCache
+ ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr R0,R0,R1 ; Set SCTLR.I bit : Instruction caches enabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableInstructionCache
+ ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ BIC R0,R0,R1 ; Clear SCTLR.I bit : Instruction caches disabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableSWPInstruction
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000400
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmEnableBranchPrediction
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00000800 ;
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDisableBranchPrediction
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00000800 ;
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmSetLowVectors
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 ; clear V bit
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmSetHighVectors
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00002000 ; Set V bit
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmV7AllDataCachesOperation
+ stmfd SP!,{r4-r12, LR}
+ mov R1, R0 ; Save Function call in R1
+ mrc p15, 1, R6, c0, c0, 1 ; Read CLIDR
+ ands R3, R6, #&7000000 ; Mask out all but Level of Coherency (LoC)
+ mov R3, R3, LSR #23 ; Cache level value (naturally aligned)
+ beq Finished
+ mov R10, #0
+
+Loop1
+ add R2, R10, R10, LSR #1 ; Work out 3xcachelevel
+ mov R12, R6, LSR R2 ; bottom 3 bits are the Cache type for this level
+ and R12, R12, #7 ; get those 3 bits alone
+ cmp R12, #2
+ blt Skip ; no cache or only instruction cache at this level
+ mcr p15, 2, R10, c0, c0, 0 ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
+ isb ; isb to sync the change to the CacheSizeID reg
+ mrc p15, 1, R12, c0, c0, 0 ; reads current Cache Size ID register (CCSIDR)
+ and R2, R12, #&7 ; extract the line length field
+ add R2, R2, #4 ; add 4 for the line length offset (log2 16 bytes)
+ ldr R4, =0x3FF
+ ands R4, R4, R12, LSR #3 ; R4 is the max number on the way size (right aligned)
+ clz R5, R4 ; R5 is the bit position of the way size increment
+ ldr R7, =0x00007FFF
+ ands R7, R7, R12, LSR #13 ; R7 is the max number of the index size (right aligned)
+
+Loop2
+ mov R9, R4 ; R9 working copy of the max way size (right aligned)
+
+Loop3
+ orr R0, R10, R9, LSL R5 ; factor in the way number and cache number into R11
+ orr R0, R0, R7, LSL R2 ; factor in the index number
+
+ blx R1
+
+ subs R9, R9, #1 ; decrement the way number
+ bge Loop3
+ subs R7, R7, #1 ; decrement the index
+ bge Loop2
+Skip
+ add R10, R10, #2 ; increment the cache number
+ cmp R3, R10
+ bgt Loop1
+
+Finished
+ dsb
+ ldmfd SP!, {r4-r12, lr}
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDataMemoryBarrier
+ dmb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmDataSynchronizationBarrier
+ dsb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmInstructionSynchronizationBarrier
+ isb
+ bx LR
+
+ RVCT_ASM_EXPORT ArmReadVBar
+ // Set the Address of the Vector Table in the VBAR register
+ mrc p15, 0, r0, c12, c0, 0
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteVBar
+ // Set the Address of the Vector Table in the VBAR register
+ mcr p15, 0, r0, c12, c0, 0
+ // Ensure the SCTLR.V bit is clear
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 ; clear V bit
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx lr
+
+ RVCT_ASM_EXPORT ArmEnableVFP
+ // Read CPACR (Coprocessor Access Control Register)
+ mrc p15, 0, r0, c1, c0, 2
+ // Enable VPF access (Full Access to CP10, CP11) (V* instructions)
+ orr r0, r0, #0x00f00000
+ // Write back CPACR (Coprocessor Access Control Register)
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ // Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.
+ mov r0, #0x40000000
+ mcr p10,#0x7,r0,c8,c0,#0
+ bx lr
+
+ RVCT_ASM_EXPORT ArmCallWFI
+ wfi
+ bx lr
+
+//Note: Return 0 in Uniprocessor implementation
+ RVCT_ASM_EXPORT ArmReadCbar
+ mrc p15, 4, r0, c15, c0, 0 //Read Configuration Base Address Register
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadMpidr
+ mrc p15, 0, r0, c0, c0, 5 ; read MPIDR
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadTpidrurw
+ mrc p15, 0, r0, c13, c0, 2 ; read TPIDRURW
+ bx lr
+
+ RVCT_ASM_EXPORT ArmWriteTpidrurw
+ mcr p15, 0, r0, c13, c0, 2 ; write TPIDRURW
+ bx lr
+
+ RVCT_ASM_EXPORT ArmIsArchTimerImplemented
+ mrc p15, 0, r0, c0, c1, 1 ; Read ID_PFR1
+ and r0, r0, #0x000F0000
+ bx lr
+
+ RVCT_ASM_EXPORT ArmReadIdPfr1
+ mrc p15, 0, r0, c0, c1, 1 ; Read ID_PFR1 Register
+ bx lr
+
+ END