summaryrefslogtreecommitdiff
path: root/Silicon/Marvell/Armada7k8k/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Marvell/Armada7k8k/Library')
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S51
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/ARM/ArmPlatformHelper.S77
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.c132
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.inf76
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.c204
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.h73
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.c158
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.inf46
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.c335
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.h50
-rw-r--r--Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.inf52
11 files changed, 1254 insertions, 0 deletions
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S
new file mode 100644
index 0000000000..72f8cfce77
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S
@@ -0,0 +1,51 @@
+//Based on ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
+//
+// Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2016, Marvell. 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 <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+ mov x29, xzr
+ ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+// IN UINTN MpId
+// );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+ and x1, x0, #ARM_CORE_MASK
+ and x0, x0, #ARM_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+// VOID
+// );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+ MOV32 (w0, FixedPcdGet32(PcdArmPrimaryCore))
+ ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+// IN UINTN MpId
+// );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+ MOV32 (w1, FixedPcdGet32(PcdArmPrimaryCoreMask))
+ and x0, x0, x1
+ MOV32 (w1, FixedPcdGet32(PcdArmPrimaryCore))
+ cmp w0, w1
+ cset x0, eq
+ ret
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/ARM/ArmPlatformHelper.S b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/ARM/ArmPlatformHelper.S
new file mode 100644
index 0000000000..21459e50a7
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/ARM/ArmPlatformHelper.S
@@ -0,0 +1,77 @@
+//Based on ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
+//
+// Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2016, Marvell. All rights reserved.
+// Copyright (c) 2017, 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>
+#include <Library/ArmLib.h>
+
+#define CCU_MC_BASE 0xF0001700
+#define CCU_MC_RCR_OFFSET 0x0
+#define CCU_MC_RCR_REMAP_EN BIT0
+#define CCU_MC_RCR_REMAP_SIZE(Size) (((Size) - 1) ^ (SIZE_1MB - 1))
+
+#define CCU_MC_RSBR_OFFSET 0x4
+#define CCU_MC_RSBR_SOURCE_BASE(Base) (((Base) >> 20) << 10)
+#define CCU_MC_RTBR_OFFSET 0x8
+#define CCU_MC_RTBR_TARGET_BASE(Base) (((Base) >> 20) << 10)
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+ .if FixedPcdGet64 (PcdSystemMemoryBase) != 0
+ .err PcdSystemMemoryBase should be 0x0 on this platform!
+ .endif
+
+ .if FixedPcdGet64 (PcdSystemMemorySize) > FixedPcdGet32 (PcdDramRemapTarget)
+ //
+ // Use the low range for UEFI itself. The remaining memory will be mapped
+ // and added to the GCD map later.
+ //
+ ADRL (r0, mSystemMemoryEnd)
+ MOV32 (r2, FixedPcdGet32 (PcdDramRemapTarget) - 1)
+ mov r3, #0
+ strd r2, r3, [r0]
+ .endif
+
+ bx lr
+
+//UINTN
+//ArmPlatformGetCorePosition (
+// IN UINTN MpId
+// );
+// With this function: CorePos = (ClusterId * 2) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+ and r1, r0, #ARM_CORE_MASK
+ and r0, r0, #ARM_CLUSTER_MASK
+ add r0, r1, r0, LSR #7
+ bx lr
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+// VOID
+// );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+ MOV32 (r0, FixedPcdGet32(PcdArmPrimaryCore))
+ bx lr
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+// IN UINTN MpId
+// );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+ MOV32 (r1, FixedPcdGet32(PcdArmPrimaryCoreMask))
+ and r0, r0, r1
+ MOV32 (r1, FixedPcdGet32(PcdArmPrimaryCore))
+ cmp r0, r1
+ moveq r0, #1
+ movne r0, #0
+ bx lr
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.c b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.c
new file mode 100644
index 0000000000..b2b415571c
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.c
@@ -0,0 +1,132 @@
+/**Based on ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+* Copyright (c) 2016, Marvell International 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 <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Ppi/ArmMpCoreInfo.h>
+
+ARM_CORE_INFO mArmada7040MpCoreInfoTable[] = {
+ {
+ // Cluster 0, Core 0
+ 0x0, 0x0,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 1
+ 0x0, 0x1,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 2
+ 0x0, 0x2,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 3
+ 0x0, 0x3,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (UINT64)0xFFFFFFFF
+ }
+};
+
+/**
+ Return the current Boot Mode
+
+ This function returns the boot reason on the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+ VOID
+ )
+{
+ return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+ Initialize controllers that must setup in the normal world
+
+ This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
+ in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+ IN UINTN MpId
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+ OUT UINTN *CoreCount,
+ OUT ARM_CORE_INFO **ArmCoreTable
+ )
+{
+ if (ArmIsMpCore()) {
+ *CoreCount = sizeof(mArmada7040MpCoreInfoTable) / sizeof(ARM_CORE_INFO);
+ *ArmCoreTable = mArmada7040MpCoreInfoTable;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gArmMpCoreInfoPpiGuid,
+ &mMpCoreInfoPpi
+ }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+ OUT UINTN *PpiListSize,
+ OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
+ )
+{
+ if (ArmIsMpCore()) {
+ *PpiListSize = sizeof(gPlatformPpiTable);
+ *PpiList = gPlatformPpiTable;
+ } else {
+ *PpiListSize = 0;
+ *PpiList = NULL;
+ }
+}
+
+
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.inf b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.inf
new file mode 100644
index 0000000000..4d4edc8565
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0Lib.inf
@@ -0,0 +1,76 @@
+# Copyright (C) 2016 Marvell International Ltd.
+#
+# Marvell BSD License Option
+#
+# If you received this File from Marvell, you may opt to use, redistribute
+# and/or modify this File under the following licensing terms.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Marvell nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Armada7040Lib
+ FILE_GUID = 3f29b642-4a49-4dfd-8f4a-205dd38432bb
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+ ArmLib
+ ComPhyLib
+ DebugLib
+ MemoryAllocationLib
+ MppLib
+ UtmiPhyLib
+
+[Sources.common]
+ Armada70x0Lib.c
+ Armada70x0LibMem.c
+
+[Sources.AArch64]
+ AArch64/ArmPlatformHelper.S
+
+[Sources.ARM]
+ ARM/ArmPlatformHelper.S
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+ gMarvellTokenSpaceGuid.PcdConfigSpaceBaseAddress
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.c b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.c
new file mode 100644
index 0000000000..f384415d7a
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.c
@@ -0,0 +1,204 @@
+/*******************************************************************************
+Copyright (C) 2016 Marvell International Ltd.
+
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of Marvell nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <Base.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "Armada70x0LibMem.h"
+
+// The total number of descriptors, including the final "end-of-table" descriptor.
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 16
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+STATIC ARM_MEMORY_REGION_DESCRIPTOR mVirtualMemoryTable[MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS];
+
+// Obtain DRAM size basing on register values filled by early firmware.
+STATIC
+UINT64
+GetDramSize (
+ IN OUT UINT64 *MemSize
+ )
+{
+ UINT64 BaseAddr;
+ UINT8 RegionCode;
+ UINT8 Cs;
+
+ *MemSize = 0;
+
+ for (Cs = 0; Cs < DRAM_MAX_CS_NUM; Cs++) {
+
+ /* Exit loop on first disabled DRAM CS */
+ if (!DRAM_CS_ENABLED (Cs)) {
+ break;
+ }
+
+ /*
+ * Sanity check for base address of next DRAM block.
+ * Only continuous space will be used.
+ */
+ BaseAddr = GET_DRAM_REGION_BASE (Cs);
+ if (BaseAddr != *MemSize) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: DRAM blocks are not contiguous, limit size to 0x%llx\n",
+ __FUNCTION__,
+ *MemSize));
+ return EFI_SUCCESS;
+ }
+
+ /* Decode area length for current CS from register value */
+ RegionCode = GET_DRAM_REGION_SIZE_CODE (Cs);
+
+ if (DRAM_REGION_SIZE_EVEN (RegionCode)) {
+ *MemSize += GET_DRAM_REGION_SIZE_EVEN (RegionCode);
+ } else if (DRAM_REGION_SIZE_ODD (RegionCode)) {
+ *MemSize += GET_DRAM_REGION_SIZE_ODD (RegionCode);
+ } else {
+ DEBUG ((DEBUG_ERROR,
+ "%a: Invalid memory region code (0x%x) for CS#%d\n",
+ __FUNCTION__,
+ RegionCode,
+ Cs));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return the Virtual Memory Map of your platform
+
+ This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+ @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+ Virtual Memory mapping. This array must be ended by a zero-filled
+ entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+ IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+ )
+{
+ UINTN Index = 0;
+ UINT64 MemSize;
+ UINT64 MemLowSize;
+ UINT64 MemHighStart;
+ UINT64 MemHighSize;
+ UINT64 ConfigSpaceBaseAddr;
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
+ EFI_STATUS Status;
+
+ ASSERT (VirtualMemoryMap != NULL);
+
+ ConfigSpaceBaseAddr = FixedPcdGet64 (PcdConfigSpaceBaseAddress);
+
+ // Obtain total memory size from the hardware.
+ Status = GetDramSize (&MemSize);
+ if (EFI_ERROR (Status)) {
+ MemSize = FixedPcdGet64 (PcdSystemMemorySize);
+ DEBUG ((DEBUG_ERROR, "Limit total memory size to %d MB\n", MemSize / 1024 / 1024));
+ }
+
+ if (DRAM_REMAP_ENABLED) {
+ MemLowSize = MIN (DRAM_REMAP_TARGET, MemSize);
+ MemHighStart = (UINT64)DRAM_REMAP_TARGET + DRAM_REMAP_SIZE;
+ MemHighSize = MemSize - MemLowSize;
+ } else {
+ MemLowSize = MIN (ConfigSpaceBaseAddr, MemSize);
+ }
+
+ ResourceAttributes = (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED
+ );
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ FixedPcdGet64 (PcdSystemMemoryBase),
+ MemLowSize
+ );
+
+ // DDR
+ mVirtualMemoryTable[Index].PhysicalBase = FixedPcdGet64 (PcdSystemMemoryBase);
+ mVirtualMemoryTable[Index].VirtualBase = FixedPcdGet64 (PcdSystemMemoryBase);
+ mVirtualMemoryTable[Index].Length = MemLowSize;
+ mVirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED;
+
+ // Configuration space
+ mVirtualMemoryTable[++Index].PhysicalBase = ConfigSpaceBaseAddr;
+ mVirtualMemoryTable[Index].VirtualBase = ConfigSpaceBaseAddr;
+ mVirtualMemoryTable[Index].Length = SIZE_4GB - ConfigSpaceBaseAddr;
+ mVirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ if (MemSize > MemLowSize) {
+ //
+ // If we have more than MemLowSize worth of DRAM, the remainder will be
+ // mapped at the top of the remapped window.
+ //
+ mVirtualMemoryTable[++Index].PhysicalBase = MemHighStart;
+ mVirtualMemoryTable[Index].VirtualBase = MemHighStart;
+ mVirtualMemoryTable[Index].Length = MemHighSize;
+ mVirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED;
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ MemHighStart,
+ MemHighSize
+ );
+ }
+
+ // End of Table
+ mVirtualMemoryTable[++Index].PhysicalBase = 0;
+ mVirtualMemoryTable[Index].VirtualBase = 0;
+ mVirtualMemoryTable[Index].Length = 0;
+ mVirtualMemoryTable[Index].Attributes = 0;
+
+ ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+ *VirtualMemoryMap = mVirtualMemoryTable;
+}
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.h b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.h
new file mode 100644
index 0000000000..cc30e4aeed
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0Lib/Armada70x0LibMem.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+Copyright (C) 2017 Marvell International Ltd.
+
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of Marvell nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#define CCU_MC_RCR_REG 0xf0001700
+#define REMAP_EN_MASK 0x1
+#define REMAP_SIZE_OFFS 20
+#define REMAP_SIZE_MASK (0xfff << REMAP_SIZE_OFFS)
+#define CCU_MC_RTBR_REG 0xf0001708
+#define TARGET_BASE_OFFS 10
+#define TARGET_BASE_MASK (0xfffff << TARGET_BASE_OFFS)
+
+#define DRAM_REMAP_ENABLED \
+ (MmioRead32 (CCU_MC_RCR_REG) & REMAP_EN_MASK)
+#define DRAM_REMAP_SIZE \
+ (MmioRead32 (CCU_MC_RCR_REG) & REMAP_SIZE_MASK) + SIZE_1MB
+#define DRAM_REMAP_TARGET \
+ (MmioRead32 (CCU_MC_RTBR_REG) << TARGET_BASE_OFFS)
+
+#define DRAM_CH0_MMAP_LOW_REG(cs) (0xf0020200 + (cs) * 0x8)
+#define DRAM_CS_VALID_ENABLED_MASK 0x1
+#define DRAM_AREA_LENGTH_OFFS 16
+#define DRAM_AREA_LENGTH_MASK (0x1f << DRAM_AREA_LENGTH_OFFS)
+#define DRAM_START_ADDRESS_L_OFFS 23
+#define DRAM_START_ADDRESS_L_MASK (0x1ff << DRAM_START_ADDRESS_L_OFFS)
+#define DRAM_CH0_MMAP_HIGH_REG(cs) (0xf0020204 + (cs) * 0x8)
+#define DRAM_START_ADDR_HTOL_OFFS 32
+
+#define DRAM_MAX_CS_NUM 8
+
+#define DRAM_CS_ENABLED(Cs) \
+ (MmioRead32 (DRAM_CH0_MMAP_LOW_REG (Cs)) & DRAM_CS_VALID_ENABLED_MASK)
+#define GET_DRAM_REGION_BASE(Cs) \
+ ((UINT64)MmioRead32 (DRAM_CH0_MMAP_HIGH_REG ((Cs))) << \
+ DRAM_START_ADDR_HTOL_OFFS) | \
+ (MmioRead32 (DRAM_CH0_MMAP_LOW_REG (Cs)) & DRAM_START_ADDRESS_L_MASK);
+#define GET_DRAM_REGION_SIZE_CODE(Cs) \
+ (MmioRead32 (DRAM_CH0_MMAP_LOW_REG ((Cs))) & \
+ DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS
+#define DRAM_REGION_SIZE_EVEN(C) (((C) >= 7) && ((C) <= 26))
+#define GET_DRAM_REGION_SIZE_EVEN(C) ((UINT64)1 << ((C) + 16))
+#define DRAM_REGION_SIZE_ODD(C) ((C) <= 4)
+#define GET_DRAM_REGION_SIZE_ODD(C) ((UINT64)0x18000000 << (C))
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.c b/Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.c
new file mode 100644
index 0000000000..53119f4150
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.c
@@ -0,0 +1,158 @@
+/** @file
+*
+* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+* Copyright (c) 2017, 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 <PiPei.h>
+
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ );
+
+STATIC
+VOID
+InitMmu (
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable
+ )
+{
+
+ VOID *TranslationTableBase;
+ UINTN TranslationTableSize;
+ RETURN_STATUS Status;
+
+ Status = ArmConfigureMmu (MemoryTable,
+ &TranslationTableBase,
+ &TranslationTableSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error: Failed to enable MMU\n"));
+ }
+}
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+ FileHandle - Handle of the file being invoked.
+ PeiServices - Describes the list of possible PEI Services.
+
+Returns:
+
+ Status - EFI_SUCCESS if the boot mode could be set
+
+--*/
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+ IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+ IN UINT64 UefiMemorySize
+ )
+{
+ ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
+ UINT64 ResourceLength;
+ EFI_PEI_HOB_POINTERS NextHob;
+ EFI_PHYSICAL_ADDRESS SecureTop;
+ EFI_PHYSICAL_ADDRESS ResourceTop;
+
+ // Get Virtual Memory Map from the Platform Library
+ ArmPlatformGetVirtualMemoryMap (&MemoryTable);
+
+ SecureTop = (EFI_PHYSICAL_ADDRESS)FixedPcdGet64 (PcdSecureRegionBase) +
+ FixedPcdGet32 (PcdSecureRegionSize);
+
+ //
+ // Search for System Memory Hob that covers the secure firmware,
+ // and punch a hole in it
+ //
+ for (NextHob.Raw = GetHobList ();
+ NextHob.Raw != NULL;
+ NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
+ NextHob.Raw)) {
+
+ if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+ (FixedPcdGet64 (PcdSecureRegionBase) >= NextHob.ResourceDescriptor->PhysicalStart) &&
+ (SecureTop <= NextHob.ResourceDescriptor->PhysicalStart +
+ NextHob.ResourceDescriptor->ResourceLength))
+ {
+ ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
+ ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
+ ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
+
+ if (FixedPcdGet64 (PcdSecureRegionBase) == NextHob.ResourceDescriptor->PhysicalStart) {
+ //
+ // This region starts right at the start of the reserved region, so we
+ // can simply move its start pointer and reduce its length by the same
+ // value
+ //
+ NextHob.ResourceDescriptor->PhysicalStart += FixedPcdGet32 (PcdSecureRegionSize);
+ NextHob.ResourceDescriptor->ResourceLength -= FixedPcdGet32 (PcdSecureRegionSize);
+
+ } else if ((NextHob.ResourceDescriptor->PhysicalStart +
+ NextHob.ResourceDescriptor->ResourceLength) == SecureTop) {
+
+ //
+ // This region ends right at the end of the reserved region, so we
+ // can simply reduce its length by the size of the region.
+ //
+ NextHob.ResourceDescriptor->ResourceLength -= FixedPcdGet32 (PcdSecureRegionSize);
+
+ } else {
+ //
+ // This region covers the reserved region. So split it into two regions,
+ // each one touching the reserved region at either end, but not covering
+ // it.
+ //
+ NextHob.ResourceDescriptor->ResourceLength = FixedPcdGet64 (PcdSecureRegionBase) -
+ NextHob.ResourceDescriptor->PhysicalStart;
+
+ // Create the System Memory HOB for the remaining region (top of the FD)
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ SecureTop,
+ ResourceTop - SecureTop);
+ }
+
+ //
+ // Reserve the memory space occupied by the secure firmware
+ //
+ BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED,
+ 0,
+ FixedPcdGet64 (PcdSecureRegionBase),
+ FixedPcdGet32 (PcdSecureRegionSize));
+
+ break;
+ }
+ NextHob.Raw = GET_NEXT_HOB (NextHob);
+ }
+
+ // Build Memory Allocation Hob
+ InitMmu (MemoryTable);
+
+ if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
+ // Optional feature that helps prevent EFI memory map fragmentation.
+ BuildMemoryTypeInformationHob ();
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.inf b/Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.inf
new file mode 100644
index 0000000000..adc5b9ac8d
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/Armada70x0MemoryInitPeiLib/Armada70x0MemoryInitPeiLib.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+# Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2017, 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 = 0x00010019
+ BASE_NAME = Armada70x0MemoryInitPeiLib
+ FILE_GUID = abc4e8a7-89a7-4aea-92bc-0e9421c4a473
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = MemoryInitPeiLib|SEC PEIM
+
+[Sources]
+ Armada70x0MemoryInitPeiLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+ ArmPlatformLib
+ DebugLib
+ HobLib
+ ArmMmuLib
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+ gMarvellTokenSpaceGuid.PcdSecureRegionBase
+ gMarvellTokenSpaceGuid.PcdSecureRegionSize
diff --git a/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.c b/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.c
new file mode 100644
index 0000000000..d671b6adc1
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.c
@@ -0,0 +1,335 @@
+/** @file
+ Implement EFI RealTimeClock runtime services via RTC Lib.
+
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2017, Marvell International 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.
+
+**/
+/**
+ Derived from:
+ ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/TimeBaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/MvHwDescLib.h>
+#include <Library/RealTimeClockLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/RealTimeClock.h>
+#include "RealTimeClockLib.h"
+
+DECLARE_A7K8K_RTC_TEMPLATE;
+STATIC EFI_EVENT mRtcVirtualAddrChangeEvent;
+STATIC UINTN mArmadaRtcBase;
+
+/**
+ According to errata FE-3124064, write to RTC TIME RTC_ALARMx registers
+ may fail. As a workaround, before actual writing to those registers,
+ issue a dummy write of 0x0 twice to RTC Status register.
+ Also, according to the datasheet, the OS should wait 5us after every
+ register write to the RTC hard macro, so that the required update
+ can occur without holding off the system bus.
+**/
+STATIC
+VOID
+RtcDelayedWrite (
+ IN UINT32 Offset,
+ IN UINT32 Value
+ )
+{
+ MmioWrite32 (mArmadaRtcBase + RTC_STATUS_REG, 0);
+ MmioWrite32 (mArmadaRtcBase + RTC_STATUS_REG, 0);
+ MmioWrite32 (mArmadaRtcBase + Offset, Value);
+ MicroSecondDelay (5);
+}
+
+/**
+ Returns the current time and date information, and the time-keeping capabilities
+ of the hardware platform.
+
+ @param Time A pointer to storage to receive a snapshot of the current time.
+ @param Capabilities An optional pointer to a buffer to receive the real time clock
+ device's capabilities.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Time is NULL.
+ @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetTime (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 RegVal;
+
+ RegVal = MmioRead32 (mArmadaRtcBase + RTC_TIME_REG);
+
+ // Convert from internal 32-bit time to UEFI time
+ EpochToEfiTime (RegVal, Time);
+
+ Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+ Time->Daylight = 0;
+
+ return Status;
+}
+
+/**
+ Sets the current local time and date information.
+
+ @param Time A pointer to the current time.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetTime (
+ IN EFI_TIME *Time
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 EpochSeconds;
+
+ // Check the input parameters are within the range specified by UEFI
+ if (!IsTimeValid (Time)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Convert time to raw seconds
+ EpochSeconds = EfiTimeToEpoch (Time);
+
+ // Issue delayed write to time register
+ RtcDelayedWrite (RTC_TIME_REG, EpochSeconds);
+
+ return Status;
+}
+
+/**
+ Returns the current wakeup alarm clock setting.
+
+ @param Enabled Indicates if the alarm is currently enabled or disabled.
+ @param Pending Indicates if the alarm signal is pending and requires acknowledgement.
+ @param Time The current alarm setting.
+
+ @retval EFI_SUCCESS The alarm settings were returned.
+ @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+ )
+{
+ UINT32 WakeupSeconds;
+
+ *Enabled = MmioRead32 (mArmadaRtcBase + RTC_IRQ_2_CONFIG_REG) & RTC_IRQ_ALARM_EN;
+
+ *Pending = MmioRead32 (mArmadaRtcBase + RTC_IRQ_STATUS_REG) & RTC_IRQ_ALARM_MASK;
+ // Ack pending alarm
+ if (Pending) {
+ MmioWrite32 (mArmadaRtcBase + RTC_IRQ_STATUS_REG, RTC_IRQ_ALARM_MASK);
+ }
+
+ WakeupSeconds = MmioRead32 (mArmadaRtcBase + RTC_ALARM_2_REG);
+ EpochToEfiTime (WakeupSeconds, Time);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the system wakeup alarm clock time.
+
+ @param Enabled Enable or disable the wakeup alarm.
+ @param Time If Enable is TRUE, the time to set the wakeup alarm for.
+
+ @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
+ Enable is FALSE, then the wakeup alarm was disabled.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
+ @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+ IN BOOLEAN Enabled,
+ OUT EFI_TIME *Time
+ )
+{
+ UINT32 WakeupSeconds;
+
+ // Convert time to raw seconds
+ WakeupSeconds = EfiTimeToEpoch (Time);
+
+ // Issue delayed write to alarm register
+ RtcDelayedWrite (RTC_ALARM_2_REG, WakeupSeconds);
+
+ if (Enabled) {
+ MmioWrite32 (mArmadaRtcBase + RTC_IRQ_2_CONFIG_REG, RTC_IRQ_ALARM_EN);
+ } else {
+ MmioWrite32 (mArmadaRtcBase + RTC_IRQ_2_CONFIG_REG, 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This can be the entry point to an application
+ written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+ @param ImageHandle Handle that identifies the loaded image.
+ @param SystemTable System Table for this image.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ MVHW_RTC_DESC *Desc = &mA7k8kRtcDescTemplate;
+ UINT8 *RtcDeviceTable, Index;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+
+ // Pick RTC device and initialize its data
+ RtcDeviceTable = (UINT8 *) PcdGetPtr (PcdRtcEnabled);
+ if (RtcDeviceTable == NULL) {
+ DEBUG ((DEBUG_ERROR, "RTC: Missing PcdRtcEnabled\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Initialize only first of enabled controllers
+ for (Index = 0; Index < PcdGetSize (PcdRtcEnabled); Index++) {
+ if (MVHW_DEV_ENABLED (Rtc, Index)) {
+ DEBUG ((DEBUG_ERROR, "RTC: Initialize controller %d\n", Index));
+ mArmadaRtcBase = Desc->RtcBaseAddresses[Index];
+ break;
+ }
+ }
+
+ // Check if any of the controllers can be initialized
+ if (mArmadaRtcBase == 0) {
+ DEBUG ((DEBUG_ERROR, "RTC: None of controllers enabled\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Declare the controller as EFI_MEMORY_RUNTIME
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ mArmadaRtcBase,
+ Desc->RtcMemSize[Index],
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RTC: Failed to add memory space\n"));
+ return Status;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (
+ mArmadaRtcBase,
+ Desc->RtcMemSize[Index],
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RTC: Failed to set memory attributes\n"));
+ goto ErrSetMem;
+ }
+
+ /* Update RTC-MBUS bridge timing parameters */
+ MmioAndThenOr32 (
+ mArmadaRtcBase + RTC_BRIDGE_TIMING_CTRL1_REG_OFFS,
+ ~RTC_READ_OUTPUT_DELAY_MASK,
+ RTC_READ_OUTPUT_DELAY_DEFAULT
+ );
+
+ // Install the protocol
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiRealTimeClockArchProtocolGuid,
+ NULL,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RTC: Failed to install the protocol\n"));
+ goto ErrSetMem;
+ }
+
+ // Register for the virtual address change event
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ LibRtcVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mRtcVirtualAddrChangeEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RTC: Failed to register virtual address change event\n"));
+ goto ErrEvent;
+ }
+
+ return Status;
+
+ErrEvent:
+ gBS->UninstallProtocolInterface (Handle, &gEfiRealTimeClockArchProtocolGuid, NULL);
+ErrSetMem:
+ gDS->RemoveMemorySpace (mArmadaRtcBase, Desc->RtcMemSize[Index]);
+
+ return Status;
+}
+
+
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Only needed if you are going to support the OS calling RTC functions in virtual mode.
+ // You will need to call EfiConvertPointer (). To convert any stored physical addresses
+ // to virtual address. After the OS transistions to calling in virtual mode, all future
+ // runtime calls will be made in virtual mode.
+ //
+ EfiConvertPointer (0x0, (VOID**)&mArmadaRtcBase);
+}
diff --git a/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.h b/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.h
new file mode 100644
index 0000000000..922f959239
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.h
@@ -0,0 +1,50 @@
+/********************************************************************************
+Copyright (C) 2017 Marvell International Ltd.
+
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of Marvell nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef __RTCLIB_H__
+#define __RTCLIB_H__
+
+/* Armada 70x0 SoC registers */
+#define RTC_STATUS_REG 0x0
+#define RTC_TIME_REG 0xC
+#define RTC_IRQ_2_CONFIG_REG 0x8
+#define RTC_IRQ_ALARM_EN 0x1
+#define RTC_ALARM_2_REG 0x14
+#define RTC_BRIDGE_TIMING_CTRL1_REG_OFFS 0x84
+#define RTC_IRQ_STATUS_REG 0x90
+#define RTC_IRQ_ALARM_MASK 0x1
+#define RTC_READ_OUTPUT_DELAY_MASK 0xFFFF
+#define RTC_READ_OUTPUT_DELAY_DEFAULT 0x1F
+
+#endif /* __RTCLIB_H__ */
diff --git a/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.inf b/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.inf
new file mode 100644
index 0000000000..2f842e8abf
--- /dev/null
+++ b/Silicon/Marvell/Armada7k8k/Library/RealTimeClockLib/RealTimeClockLib.inf
@@ -0,0 +1,52 @@
+#/** @file
+#
+# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2017, Marvell International 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.
+#
+#**/
+#/**
+# Derived from:
+# ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+#
+#**/
+
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = ArmadaRealTimeClockLib
+ FILE_GUID = fa81e889-045b-4c96-9093-742554fd0588
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RealTimeClockLib
+
+[Sources.common]
+ RealTimeClockLib.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+ DebugLib
+ DxeServicesTableLib
+ IoLib
+ PcdLib
+ TimeBaseLib
+ TimerLib
+ UefiRuntimeLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
+
+[Pcd]
+ gMarvellTokenSpaceGuid.PcdRtcEnabled