summaryrefslogtreecommitdiff
path: root/Silicon/AMD/Styx/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/AMD/Styx/Library')
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.c77
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.inf37
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxLib/AArch64/Helper.S78
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLib.inf76
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf67
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxLib/Styx.c164
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxLib/StyxMem.c118
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.c196
-rw-r--r--Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.inf55
-rw-r--r--Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.c185
-rw-r--r--Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.inf92
-rw-r--r--Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.c277
-rw-r--r--Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.inf57
-rw-r--r--Silicon/AMD/Styx/Library/ResetSystemLib/ResetSystemLib.inf47
-rw-r--r--Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c543
-rw-r--r--Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.inf65
16 files changed, 2134 insertions, 0 deletions
diff --git a/Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.c b/Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.c
new file mode 100644
index 0000000000..d8b70f56fa
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.c
@@ -0,0 +1,77 @@
+/** @file
+
+ Copyright (c) 2014 - 2016, AMD 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.
+
+**/
+
+#include <AmdStyxHelperLib.h>
+
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+
+extern EFI_SYSTEM_TABLE *gST;
+
+#pragma pack(push, 1)
+typedef struct {
+ UINT32 MpId;
+ UINT32 PmuSpi;
+} PMU_INFO;
+
+PMU_INFO mPmuInfo[] = {
+ {0x000, 7},
+ {0x001, 8},
+ {0x100, 9},
+ {0x101, 10},
+ {0x200, 11},
+ {0x201, 12},
+ {0x300, 13},
+ {0x301, 14}
+};
+#pragma pack(pop)
+
+#define MAX_CPUS sizeof(mPmuInfo) / sizeof(PMU_INFO)
+
+EFI_STATUS
+AmdStyxGetPmuSpiFromMpId (
+ UINT32 MpId,
+ UINT32 *PmuSpi
+ )
+{
+ UINT32 i;
+
+ for (i = 0; i < MAX_CPUS; ++i) {
+ if (mPmuInfo[ i ].MpId == MpId) {
+ *PmuSpi = mPmuInfo[ i ].PmuSpi;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+ARM_CORE_INFO *
+AmdStyxGetArmCoreInfoTable (
+ OUT UINTN *NumEntries
+ )
+{
+ EFI_HOB_GUID_TYPE *Hob;
+
+ ASSERT (NumEntries != NULL);
+
+ Hob = GetFirstGuidHob (&gAmdStyxMpCoreInfoGuid);
+ if (Hob == NULL) {
+ return NULL;
+ }
+
+ *NumEntries = GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (ARM_CORE_INFO);
+
+ return GET_GUID_HOB_DATA (Hob);
+}
diff --git a/Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.inf b/Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.inf
new file mode 100644
index 0000000000..17681d9ed5
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxHelperLib/AmdStyxHelperLib.inf
@@ -0,0 +1,37 @@
+#/** @file
+#
+# Copyright (c) 2014 - 2016, AMD 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.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AmdStyxHelperLib
+ FILE_GUID = a2a9afbb-6776-4585-8a81-f82f98b4ea53
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = AmdStyxHelperLib
+
+[Sources.common]
+ AmdStyxHelperLib.c
+
+[LibraryClasses]
+ HobLib
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AmdModulePkg/AmdModulePkg.dec
+ OpenPlatformPkg/Platforms/AMD/Styx/AmdStyx.dec
+
+[Guids]
+ gAmdStyxMpCoreInfoGuid
diff --git a/Silicon/AMD/Styx/Library/AmdStyxLib/AArch64/Helper.S b/Silicon/AMD/Styx/Library/AmdStyxLib/AArch64/Helper.S
new file mode 100644
index 0000000000..b7ec02f0e6
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxLib/AArch64/Helper.S
@@ -0,0 +1,78 @@
+#/**
+#
+# Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>
+# Copyright (c) 2014 - 2016, AMD 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.
+#
+#**/
+#/**
+# Derived from:
+# ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSMHelper.S
+#
+#**/
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+PrimaryCoreMpid: .word 0x0
+PrimaryCoreBoot: .word 0x0
+
+//VOID
+//ArmPlatformPeiBootAction (
+// VOID
+// );
+ASM_FUNC(ArmPlatformPeiBootAction)
+ ldr w0, PrimaryCoreBoot
+ cbnz w0, 1f
+
+ // Save the primary CPU MPID
+ mrs x0, mpidr_el1
+ adr x2, PrimaryCoreMpid
+ mov w1, #1
+ stp w0, w1, [x2]
+1:
+ ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+// VOID
+// );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+ ldr w0, PrimaryCoreMpid
+ ret
+
+# IN None
+# OUT x0 = number of cores present in the system
+ASM_FUNC(ArmGetCpuCountPerCluster)
+ MOV32 (w0, FixedPcdGet32 (PcdCoreCount))
+ ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+// IN UINTN MpId
+// );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+ ldr w1, PrimaryCoreMpid
+
+ cmp w0, w1
+ cset x0, eq
+ ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+// IN UINTN MpId
+// );
+// With this function: CorePos = (ClusterId * 2) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+ and x1, x0, #ARM_CORE_MASK
+ and x0, x0, #ARM_CLUSTER_MASK
+ add x0, x1, x0, LSR #7
+ ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLib.inf b/Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLib.inf
new file mode 100644
index 0000000000..76ea730990
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLib.inf
@@ -0,0 +1,76 @@
+#/* @file
+#
+# Copyright (c) 2011-2014, ARM Limited. All rights reserved.<BR>
+# Copyright (c) 2014 - 2016, AMD 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.
+#
+#*/
+#/**
+# Derived from:
+# ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AmdStyxLib
+ FILE_GUID = 256ee872-5a3e-4b6e-afd6-63c49ba3d7ba
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/AMD/Styx/AmdModulePkg/AmdModulePkg.dec
+ Silicon/AMD/Styx/AmdStyx.dec
+
+[LibraryClasses]
+ ArmLib
+ HobLib
+ DebugLib
+
+[Sources.common]
+ Styx.c
+ StyxMem.c
+
+[Sources.AARCH64]
+ AArch64/Helper.S | GCC
+
+[Guids]
+ gAmdStyxMpCoreInfoGuid ## CONSUMER
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+ gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWMemoryBase
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWMemorySize
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
+
+[Depex]
+ gAmdStyxPlatInitPpiGuid
diff --git a/Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf b/Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf
new file mode 100644
index 0000000000..b067f72899
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf
@@ -0,0 +1,67 @@
+#/* @file
+#
+# Copyright (c) 2011-2012, ARM Limited. All rights reserved.<BR>
+# Copyright (c) 2014 - 2016, AMD 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.
+#
+#*/
+#/**
+# Derived from:
+# ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AmdStyxLibSec
+ FILE_GUID = 2228e985-60ae-406e-bdf0-410c6750c7d2
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/AMD/Styx/AmdModulePkg/AmdModulePkg.dec
+ Silicon/AMD/Styx/AmdStyx.dec
+
+[LibraryClasses]
+ ArmLib
+ HobLib
+ DebugLib
+
+[Sources.common]
+ Styx.c
+
+[Sources.AARCH64]
+ AArch64/Helper.S | GCC
+
+[Guids]
+ gAmdStyxMpCoreInfoGuid ## CONSUMER
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+ gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Silicon/AMD/Styx/Library/AmdStyxLib/Styx.c b/Silicon/AMD/Styx/Library/AmdStyxLib/Styx.c
new file mode 100644
index 0000000000..f17a960d60
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxLib/Styx.c
@@ -0,0 +1,164 @@
+/** @file
+*
+* Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>
+* Copyright (c) 2014 - 2016, AMD 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.
+*
+**/
+/**
+ Derived from:
+ ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Guid/ArmMpCoreInfo.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+
+
+extern EFI_GUID gAmdStyxMpCoreInfoGuid;
+
+
+UINTN
+ArmGetCpuCountPerCluster (
+ VOID
+ );
+
+
+/**
+ Return the current Boot Mode
+
+ This function returns the boot reason on the platform
+
+ @return Return the current Boot Mode of 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/Pei or ArmPlatformPkg/Pei/PlatformPeim
+ in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+ IN UINTN MpId
+ )
+{
+ if (!ArmPlatformIsPrimaryCore (MpId)) {
+ return RETURN_SUCCESS;
+ }
+
+ // XXX Place holder XXX ...
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Initialize the system (or sometimes called permanent) memory
+
+ This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+ VOID
+ )
+{
+ // Nothing to do here
+}
+
+
+//
+// Return list of cores in the system
+//
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+ OUT UINTN *ArmCoreCount,
+ OUT ARM_CORE_INFO **ArmCoreInfoTable
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ if (ArmIsMpCore()) {
+ // Iterate through the HOBs and find if there is ARM PROCESSOR ENTRY HOB
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+ // Check for Correct HOB type
+ if ((GET_HOB_TYPE (Hob)) == EFI_HOB_TYPE_GUID_EXTENSION) {
+ // Check for correct GUID type
+ if (CompareGuid(&(Hob.Guid->Name), &gAmdStyxMpCoreInfoGuid)) {
+ *ArmCoreInfoTable = (ARM_CORE_INFO *) GET_GUID_HOB_DATA(Hob);
+ *ArmCoreCount = GET_GUID_HOB_DATA_SIZE(Hob)/sizeof(ARM_CORE_INFO);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+
+ 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/AMD/Styx/Library/AmdStyxLib/StyxMem.c b/Silicon/AMD/Styx/Library/AmdStyxLib/StyxMem.c
new file mode 100644
index 0000000000..3b82132d08
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxLib/StyxMem.c
@@ -0,0 +1,118 @@
+/** @file
+*
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.<BR>
+* Copyright (c) 2014 - 2016, AMD 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.
+*
+**/
+/**
+ Derived from:
+ ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c
+
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+
+#if !defined(MDEPKG_NDEBUG)
+
+static const char *tblAttrDesc[] =
+{
+ "UNCACHED_UNBUFFERED ",
+ "NONSECURE_UNCACHED_UNBUFFERED",
+ "WRITE_BACK ",
+ "NONSECURE_WRITE_BACK ",
+ "WRITE_THROUGH ",
+ "NONSECURE_WRITE_THROUGH ",
+ "DEVICE ",
+ "NONSECURE_DEVICE "
+};
+#endif
+
+#define LOG_MEM(desc) DEBUG ((EFI_D_ERROR, desc, VirtualMemoryTable[Index].PhysicalBase, \
+ ( VirtualMemoryTable[Index].PhysicalBase+VirtualMemoryTable[Index].Length - 1), \
+ VirtualMemoryTable[Index].Length, tblAttrDesc[VirtualMemoryTable[Index].Attributes]));
+
+
+// Number of Virtual Memory Map Descriptors
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 16
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+/**
+ 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
+ )
+{
+ ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes;
+ UINTN Index = 0;
+ ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
+
+ ASSERT(VirtualMemoryMap != NULL);
+
+ VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+ if (VirtualMemoryTable == NULL) {
+ return;
+ }
+
+ if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
+ CacheAttributes = DDR_ATTRIBUTES_CACHED;
+ } else {
+ CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+ }
+
+ DEBUG ((EFI_D_ERROR, " Memory Map\n------------------------------------------------------------------------\n"));
+ DEBUG ((EFI_D_ERROR, "Description : START - END [ SIZE ] { ATTR }\n"));
+
+ // 0xE000_0000 - 0xEFFF_FFFF: Mapped I/O space
+ VirtualMemoryTable[Index].PhysicalBase = 0xE0000000UL;
+ VirtualMemoryTable[Index].VirtualBase = 0xE0000000UL;
+ VirtualMemoryTable[Index].Length = SIZE_256MB;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+ LOG_MEM ("I/O Space [Platform MMIO] : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+ // 0xF000_0000 - 0xFFFF_FFFF: PCI config space
+ VirtualMemoryTable[++Index].PhysicalBase = 0xF0000000UL;
+ VirtualMemoryTable[Index].VirtualBase = 0xF0000000UL;
+ VirtualMemoryTable[Index].Length = SIZE_256MB;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+ LOG_MEM ("I/O Space [PCI config space] : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+ // DRAM
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize);
+ VirtualMemoryTable[Index].Attributes = CacheAttributes;
+ LOG_MEM ("DRAM : 0x%016lx - 0x%016lx [ 0x%016lx ] { %a }\n");
+
+ // End of Table
+ VirtualMemoryTable[++Index].PhysicalBase = 0;
+ VirtualMemoryTable[Index].VirtualBase = 0;
+ VirtualMemoryTable[Index].Length = 0;
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+ *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.c b/Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.c
new file mode 100644
index 0000000000..8d8c76a0f7
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.c
@@ -0,0 +1,196 @@
+/** @file
+ PCI Host Bridge Library instance for AMD Seattle SOC
+
+ Copyright (c) 2016, 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.
+
+**/
+#include <PiDxe.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#pragma pack(1)
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID(0x0A08), // PCI Express
+ 0
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+ L"Mem", L"I/O", L"Bus"
+};
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+ UINTN *Count
+ )
+{
+ PCI_ROOT_BRIDGE *RootBridge;
+
+ *Count = 1;
+ RootBridge = AllocateZeroPool (*Count * sizeof *RootBridge);
+
+ RootBridge->Segment = 0;
+
+ RootBridge->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
+ EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
+ EFI_PCI_ATTRIBUTE_ISA_IO_16 |
+ EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
+ EFI_PCI_ATTRIBUTE_VGA_MEMORY |
+ EFI_PCI_ATTRIBUTE_VGA_IO_16 |
+ EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+ RootBridge->Attributes = RootBridge->Supports;
+
+ RootBridge->DmaAbove4G = TRUE;
+
+ RootBridge->AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
+ EFI_PCI_HOST_BRIDGE_MEM64_DECODE ;
+
+ RootBridge->Bus.Base = PcdGet32 (PcdPciBusMin);
+ RootBridge->Bus.Limit = PcdGet32 (PcdPciBusMax);
+ RootBridge->Io.Base = PcdGet64 (PcdPciIoBase);
+ RootBridge->Io.Limit = PcdGet64 (PcdPciIoBase) + PcdGet64 (PcdPciIoSize) - 1;
+ RootBridge->Mem.Base = PcdGet32 (PcdPciMmio32Base);
+ RootBridge->Mem.Limit = PcdGet32 (PcdPciMmio32Base) + PcdGet32 (PcdPciMmio32Size) - 1;
+ RootBridge->MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
+ RootBridge->MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) + PcdGet64 (PcdPciMmio64Size) - 1;
+
+ //
+ // No separate ranges for prefetchable and non-prefetchable BARs
+ //
+ RootBridge->PMem.Base = MAX_UINT64;
+ RootBridge->PMem.Limit = 0;
+ RootBridge->PMemAbove4G.Base = MAX_UINT64;
+ RootBridge->PMemAbove4G.Limit = 0;
+
+ ASSERT (FixedPcdGet64 (PcdPciMmio32Translation) == 0);
+ ASSERT (FixedPcdGet64 (PcdPciMmio64Translation) == 0);
+
+ RootBridge->NoExtendedConfigSpace = FALSE;
+
+ RootBridge->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath;
+
+ return RootBridge;
+}
+
+/**
+ Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
+
+ @param Bridges The root bridge instances array.
+ @param Count The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+ FreePool (Bridges);
+}
+
+/**
+ Inform the platform that the resource conflict happens.
+
+ @param HostBridgeHandle Handle of the Host Bridge.
+ @param Configuration Pointer to PCI I/O and PCI memory resource
+ descriptors. The Configuration contains the resources
+ for all the root bridges. The resource for each root
+ bridge is terminated with END descriptor and an
+ additional END is appended indicating the end of the
+ entire resources. The resource descriptor field
+ values follow the description in
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+ EFI_HANDLE HostBridgeHandle,
+ VOID *Configuration
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN RootBridgeIndex;
+ DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+ RootBridgeIndex = 0;
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+ while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+ for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+ ASSERT (Descriptor->ResType <
+ (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
+ sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
+ )
+ );
+ DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+ mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+ Descriptor->AddrLen, Descriptor->AddrRangeMax
+ ));
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
+ Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+ ((Descriptor->SpecificFlag &
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+ ) != 0) ? L" (Prefetchable)" : L""
+ ));
+ }
+ }
+ //
+ // Skip the END descriptor for root bridge
+ //
+ ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+ );
+ }
+}
diff --git a/Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.inf b/Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.inf
new file mode 100644
index 0000000000..3fdaf14d8c
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/AmdStyxPciHostBridgeLib/AmdStyxPciHostBridgeLib.inf
@@ -0,0 +1,55 @@
+## @file
+# PCI Host Bridge Library instance for AMD Seattle SOC
+#
+# Copyright (c) 2016, 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 = 0x00010005
+ BASE_NAME = AmdStyxPciHostBridgeLib
+ FILE_GUID = 05E7AB83-EF8D-482D-80F8-905B73377A15
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = AARCH64
+#
+
+[Sources]
+ AmdStyxPciHostBridgeLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdPciBusMin
+ gArmTokenSpaceGuid.PcdPciBusMax
+ gArmTokenSpaceGuid.PcdPciIoBase
+ gArmTokenSpaceGuid.PcdPciIoSize
+ gArmTokenSpaceGuid.PcdPciMmio32Base
+ gArmTokenSpaceGuid.PcdPciMmio32Size
+ gArmTokenSpaceGuid.PcdPciMmio32Translation
+ gArmTokenSpaceGuid.PcdPciMmio64Base
+ gArmTokenSpaceGuid.PcdPciMmio64Size
+ gArmTokenSpaceGuid.PcdPciMmio64Translation
diff --git a/Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.c b/Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.c
new file mode 100644
index 0000000000..70821d1b12
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.c
@@ -0,0 +1,185 @@
+/** @file
+
+ Copyright (c) 2011-2014, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2014 - 2016 AMD 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.
+
+**/
+/**
+ Derived from:
+ ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.c
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ );
+
+VOID
+InitMmu (
+ VOID
+ )
+{
+ ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
+ VOID *TranslationTableBase;
+ UINTN TranslationTableSize;
+ RETURN_STATUS Status;
+
+ // Get Virtual Memory Map from the Platform Library
+ ArmPlatformGetVirtualMemoryMap (&MemoryTable);
+
+ // Note: Because we called PeiServicesInstallPeiMemory() before to call
+ // InitMmu() the MMU Page Table resides in DRAM (even at the top
+ // of DRAM as it is the first permanent memory allocation)
+ Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
+ }
+}
+
+STATIC
+VOID
+MoveNvStoreImage (
+ VOID
+ )
+{
+ VOID *OldBase, *NewBase;
+ UINTN Size;
+
+ //
+ // Move the in-memory image of the NV store firmware volume to a dynamically
+ // allocated buffer. This gets rid of the annoying static memory reservation
+ // at the base of memory where all other UEFI allocations are near the top.
+ //
+ OldBase = (VOID *)FixedPcdGet64 (PcdFlashNvStorageOriginalBase);
+
+ Size = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+ NewBase = AllocateAlignedRuntimePages (EFI_SIZE_TO_PAGES (Size), SIZE_64KB);
+ ASSERT (NewBase != NULL);
+
+ CopyMem (NewBase, OldBase, Size);
+
+ DEBUG ((EFI_D_INFO, "%a: Relocating NV store FV from %p to %p\n",
+ __FUNCTION__, OldBase, NewBase));
+
+ PcdSet64 (PcdFlashNvStorageVariableBase64, (UINT64)NewBase);
+
+ PcdSet64 (PcdFlashNvStorageFtwWorkingBase64, (UINT64)NewBase +
+ FixedPcdGet32 (PcdFlashNvStorageVariableSize));
+
+ PcdSet64 (PcdFlashNvStorageFtwSpareBase64, (UINT64)NewBase +
+ FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize));
+}
+
+/*++
+
+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
+ )
+{
+ UINT64 Base, Size;
+
+ // Ensure PcdSystemMemorySize has been set
+ ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
+
+ //
+ // Now, the permanent memory has been installed, we can call AllocatePages()
+ //
+
+ Base = PcdGet64 (PcdSystemMemoryBase);
+ Size = PcdGet64 (PcdSystemMemorySize);
+ if (FixedPcdGetBool (PcdTrustedFWSupport)) {
+
+ //
+ // For now, we assume that the trusted firmware region is at the base of
+ // system memory, since that is much easier to deal with.
+ //
+ ASSERT (Base == PcdGet64 (PcdTrustedFWMemoryBase));
+
+ Base += PcdGet64 (PcdTrustedFWMemorySize);
+ Size -= PcdGet64 (PcdTrustedFWMemorySize);
+
+ // Reserved Trusted Firmware region
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ( 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 ),
+ PcdGet64 (PcdTrustedFWMemoryBase),
+ PcdGet64 (PcdTrustedFWMemorySize)
+ );
+
+ BuildMemoryAllocationHob (
+ PcdGet64 (PcdTrustedFWMemoryBase),
+ PcdGet64 (PcdTrustedFWMemorySize),
+ EfiReservedMemoryType
+ );
+ }
+
+ // Declare system memory
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ( 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 ),
+ Base,
+ Size
+ );
+
+ // Build Memory Allocation Hob
+ InitMmu ();
+
+ // Optional feature that helps prevent EFI memory map fragmentation.
+ if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
+ BuildMemoryTypeInformationHob ();
+ }
+
+ MoveNvStoreImage ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.inf b/Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.inf
new file mode 100644
index 0000000000..724d71645d
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/MemoryInitPei/MemoryInitPeiLib.inf
@@ -0,0 +1,92 @@
+#/** @file
+#
+# Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2014 - 2016, AMD 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.
+#**/
+#/**
+# Derived from:
+# ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AmdStyxMemoryInitPeiLib
+ FILE_GUID = 25466f78-a75a-4aae-be09-a68a347c3228
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = MemoryInitPeiLib|SEC PEIM
+
+[Sources]
+ MemoryInitPeiLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/AMD/Styx/AmdModulePkg/AmdModulePkg.dec
+ Silicon/AMD/Styx/AmdStyx.dec
+
+[LibraryClasses]
+ DebugLib
+ HobLib
+ ArmMmuLib
+ ArmPlatformLib
+ PcdLib
+
+[Ppis]
+ gAmdStyxPlatInitPpiGuid ## CONSUMER
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWSupport
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWMemoryBase
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWMemorySize
+
+ gAmdStyxTokenSpaceGuid.PcdIscpSupport
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gAmdStyxTokenSpaceGuid.PcdFlashNvStorageOriginalBase
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
+
+[Depex]
+ gAmdStyxPlatInitPpiGuid
diff --git a/Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.c b/Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.c
new file mode 100644
index 0000000000..1b926242b5
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.c
@@ -0,0 +1,277 @@
+/** @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) 2014 - 2016, AMD 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.
+
+**/
+/**
+ Derived from:
+ ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/RealTimeClockLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Guid/EventGroup.h>
+
+#include <Protocol/AmdIscpDxeProtocol.h>
+#include <Iscp.h>
+
+extern EFI_BOOT_SERVICES *gBS;
+
+AMD_ISCP_DXE_PROTOCOL *mRtcIscpDxeProtocol = NULL;
+STATIC EFI_EVENT mRtcVirtualAddrChangeEvent;
+
+
+/**
+ 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
+ )
+{
+ ISCP_RTC_INFO RtcInfo;
+ EFI_STATUS Status;
+
+ if (!FixedPcdGetBool (PcdIscpSupport)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (mRtcIscpDxeProtocol == NULL) {
+ DEBUG((EFI_D_ERROR, "RTC: ISCP DXE Protocol is NULL!\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Fill in Time and Capabilities via data from you RTC
+ //
+ Status = mRtcIscpDxeProtocol->AmdExecuteGetRtc (
+ mRtcIscpDxeProtocol,
+ &RtcInfo
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "RTC: Failed GetRtc() via ISCP - Status = %r \n", Status));
+ return Status;
+ }
+
+ Time->Year = RtcInfo.Year;
+ Time->Month = RtcInfo.Month;
+ Time->Day = RtcInfo.Day;
+ Time->Hour = RtcInfo.Hour;
+ Time->Minute = RtcInfo.Minute;
+ Time->Second = RtcInfo.Second;
+
+ 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;
+ ISCP_RTC_INFO RtcInfo;
+
+ if (!FixedPcdGetBool (PcdIscpSupport)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Use Time, to set the time in your RTC hardware
+ //
+ RtcInfo.Year = Time->Year;
+ RtcInfo.Month = Time->Month;
+ RtcInfo.Day = Time->Day;
+ RtcInfo.Hour = Time->Hour;
+ RtcInfo.Minute = Time->Minute;
+ RtcInfo.Second = Time->Second;
+
+ if (mRtcIscpDxeProtocol == NULL) {
+ DEBUG((EFI_D_ERROR, "RTC: ISCP DXE Protocol is NULL!\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = mRtcIscpDxeProtocol->AmdExecuteSetRtc (
+ mRtcIscpDxeProtocol,
+ &RtcInfo
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "RTC: Failed SetRtc() via ISCP - Status = %r \n", Status));
+ return Status;
+ }
+
+ 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
+ )
+{
+ // Not a required feature
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ 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
+ )
+{
+ // Not a required feature
+ return EFI_UNSUPPORTED;
+}
+
+
+
+/**
+ 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
+ )
+{
+ EFI_STATUS Status;
+
+ if (!FixedPcdGetBool (PcdIscpSupport)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Do some initialization if required to turn on the RTC
+ //
+ Status = gBS->LocateProtocol (
+ &gAmdIscpDxeProtocolGuid,
+ NULL,
+ (VOID **)&mRtcIscpDxeProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "RTC: Failed to Locate ISCP DXE Protocol - Status = %r \n", Status));
+ return Status;
+ }
+
+ //
+ // Register for the virtual address change event
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ LibRtcVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mRtcVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ 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.
+ //
+ if (FixedPcdGetBool (PcdIscpSupport)) {
+ EfiConvertPointer (0x0, (VOID**)&mRtcIscpDxeProtocol);
+ }
+}
+
+
+
diff --git a/Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.inf b/Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.inf
new file mode 100644
index 0000000000..cd9418c9b7
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/RealTimeClockLib/RealTimeClockLib.inf
@@ -0,0 +1,57 @@
+#/** @file
+#
+# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2014 - 2016, AMD 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.
+#
+#**/
+#/**
+# Derived from:
+# ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AmdStyxRealTimeClockLib
+ FILE_GUID = fd922639-f4ee-4d2f-955b-804e60df1e68
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RealTimeClockLib
+
+[Sources.common]
+ RealTimeClockLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/AMD/Styx/AmdModulePkg/AmdModulePkg.dec
+ Silicon/AMD/Styx/AmdStyx.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+ UefiRuntimeLib
+ DxeServicesTableLib
+
+[FixedPcd]
+ gAmdStyxTokenSpaceGuid.PcdIscpSupport
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
+
+[Protocols]
+ gAmdIscpDxeProtocolGuid ## CONSUMER
+
+[Depex]
+ gAmdIscpDxeProtocolGuid
+
+
+
diff --git a/Silicon/AMD/Styx/Library/ResetSystemLib/ResetSystemLib.inf b/Silicon/AMD/Styx/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..5a99fd7938
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,47 @@
+#/** @file
+# Reset System lib using PSCI hypervisor or secure monitor calls
+#
+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2014 - 2016, AMD 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.
+#
+#**/
+#/**
+# Derived from:
+# ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AmdStyxResetSystemLib
+ FILE_GUID = 624f6cc6-c38f-4897-b3b7-8a601701291b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = EfiResetSystemLib
+
+[Sources.common]
+ ResetSystemLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/AMD/Styx/AmdModulePkg/AmdModulePkg.dec
+ Silicon/AMD/Styx/AmdStyx.dec
+
+[LibraryClasses]
+ PcdLib
+ BaseLib
+ ArmSmcLib
+
+[FixedPcd]
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWSupport
diff --git a/Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c b/Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c
new file mode 100644
index 0000000000..7e8f918b11
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c
@@ -0,0 +1,543 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiDxe.h>
+
+#include <Guid/ArmMpCoreInfo.h>
+
+#include <libfdt.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/AmdMpCoreInfo.h>
+
+#define PMU_INT_FLAG_SPI 0
+#define PMU_INT_TYPE_HIGH_LEVEL 4
+
+//
+// PMU interrupts per core
+//
+#pragma pack(push, 1)
+typedef struct {
+ UINT32 Flag; // 0 == SPI
+ UINT32 IntId; // GSIV == IntId+32
+ UINT32 Type; // 4 == Level-Sensitive, Active-High
+} PMU_INTERRUPT;
+#pragma pack(pop)
+
+STATIC
+BOOLEAN
+ClusterInRange (
+ IN ARM_CORE_INFO *ArmCoreInfoTable,
+ IN UINTN ClusterId,
+ IN UINTN LowIndex,
+ IN UINTN HighIndex
+ )
+{
+ do {
+ if (ClusterId == ArmCoreInfoTable[LowIndex].ClusterId)
+ return TRUE;
+ } while (++LowIndex <= HighIndex);
+
+ return FALSE;
+}
+
+
+STATIC
+UINTN
+NumberOfCoresInCluster (
+ IN ARM_CORE_INFO *ArmCoreInfoTable,
+ IN UINTN NumberOfEntries,
+ IN UINTN ClusterId
+ )
+{
+ UINTN Index, Cores;
+
+ Cores = 0;
+ for (Index = 0; Index < NumberOfEntries; ++Index) {
+ if (ClusterId == ArmCoreInfoTable[Index].ClusterId)
+ ++Cores;
+ }
+
+ return Cores;
+}
+
+
+STATIC
+UINTN
+NumberOfClustersInTable (
+ IN ARM_CORE_INFO *ArmCoreInfoTable,
+ IN UINTN NumberOfEntries
+ )
+{
+ UINTN Index, Cores, Clusters, ClusterId;
+
+ Index = 0;
+ Clusters = 0;
+ Cores = NumberOfEntries;
+ while (Cores) {
+ ++Clusters;
+ ClusterId = ArmCoreInfoTable[Index].ClusterId;
+ Cores -= NumberOfCoresInCluster (ArmCoreInfoTable,
+ NumberOfEntries,
+ ClusterId);
+ if (Cores) {
+ do {
+ ++Index;
+ } while (ClusterInRange (ArmCoreInfoTable,
+ ArmCoreInfoTable[Index].ClusterId,
+ 0, Index-1));
+ }
+ }
+
+ return Clusters;
+}
+
+
+STATIC
+INT32
+fdt_alloc_phandle (
+ IN VOID *Fdt
+ )
+{
+ INT32 Offset;
+ INT32 Phandle;
+
+ Phandle = 0;
+
+ for (Offset = fdt_next_node (Fdt, -1, NULL); Offset >= 0;
+ Offset = fdt_next_node (Fdt, Offset, NULL)) {
+ Phandle = MAX (Phandle, fdt_get_phandle (Fdt, Offset));
+ }
+
+ return Phandle + 1;
+}
+
+STATIC
+VOID
+SetDeviceStatus (
+ IN VOID *Fdt,
+ IN CONST CHAR8 *Device,
+ IN BOOLEAN Enable
+ )
+{
+ INT32 Node;
+ INT32 SubNode;
+ INT32 Rc;
+
+ Node = fdt_subnode_offset (Fdt, 0, "smb");
+ if (Node >= 0) {
+ SubNode = fdt_subnode_offset (Fdt, Node, Device);
+ if (SubNode >= 0) {
+ Rc = fdt_setprop_string (Fdt, SubNode, "status",
+ Enable ? "okay" : "disabled");
+ if (Rc) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: Could not set 'status' property for '%a' node\n",
+ __FUNCTION__, Device));
+ }
+ }
+ }
+}
+
+#if DO_XGBE
+
+#define MAC_ADDRESS_BYTES 6
+
+STATIC
+VOID
+SetMacAddress (
+ IN VOID *Fdt,
+ IN CONST CHAR8 *Device,
+ IN UINT64 MacAddress
+ )
+{
+ INT32 Node;
+ INT32 SubNode;
+ INT32 Rc;
+
+ Node = fdt_subnode_offset (Fdt, 0, "smb");
+ if (Node >= 0) {
+ SubNode = fdt_subnode_offset (Fdt, Node, Device);
+ if (SubNode >= 0) {
+ Rc = fdt_setprop (Fdt, SubNode, "mac-address", (VOID *)&MacAddress,
+ MAC_ADDRESS_BYTES);
+ if (Rc) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: Could not set 'mac-address' property for '%a' node\n",
+ __FUNCTION__, Device));
+ }
+ }
+ }
+}
+
+#endif
+
+STATIC
+VOID
+DisableSmmu (
+ IN VOID *Fdt,
+ IN CONST CHAR8 *IommuPropName,
+ IN CONST CHAR8 *SmmuNodeName,
+ IN CONST CHAR8 *DeviceNodeName
+ )
+{
+ INT32 Node;
+ INT32 Error;
+
+ Node = fdt_path_offset (Fdt, DeviceNodeName);
+ if (Node <= 0) {
+ DEBUG ((DEBUG_WARN, "%a: Failed to find path %s: %a\n",
+ __FUNCTION__, DeviceNodeName, fdt_strerror (Node)));
+ return;
+ }
+
+ Error = fdt_delprop (Fdt, Node, IommuPropName);
+ if (Error != 0) {
+ DEBUG ((DEBUG_WARN, "%a: Failed to delete property %a: %a\n",
+ __FUNCTION__, IommuPropName, fdt_strerror (Error)));
+ return;
+ }
+
+ Node = fdt_path_offset (Fdt, SmmuNodeName);
+ if (Node <= 0) {
+ DEBUG ((DEBUG_WARN, "%a: Failed to find path %s: %a\n",
+ __FUNCTION__, SmmuNodeName, fdt_strerror (Node)));
+ return;
+ }
+
+ Error = fdt_del_node (Fdt, Node);
+ if (Error != 0) {
+ DEBUG ((DEBUG_WARN, "%a: Failed to delete node %a: %a\n",
+ __FUNCTION__, SmmuNodeName, fdt_strerror (Error)));
+ }
+}
+
+#define STYX_SOC_VERSION_MASK 0xFFF
+#define STYX_SOC_VERSION_A0 0x000
+#define STYX_SOC_VERSION_B0 0x010
+#define STYX_SOC_VERSION_B1 0x011
+
+STATIC
+VOID
+SetSocIdStatus (
+ IN VOID *Fdt
+ )
+{
+ UINT32 SocId;
+ BOOLEAN IsRevB1;
+ BOOLEAN DisableXgbeSmmus;
+
+ SocId = PcdGet32 (PcdSocCpuId);
+ IsRevB1 = (SocId & STYX_SOC_VERSION_MASK) >= STYX_SOC_VERSION_B1;
+
+ SetDeviceStatus (Fdt, "sata@e0d00000",
+ IsRevB1 && FixedPcdGet8 (PcdSata1PortCount) > 0);
+ SetDeviceStatus (Fdt, "gpio@e0020000", IsRevB1);
+ SetDeviceStatus (Fdt, "gpio@e0030000", IsRevB1);
+ SetDeviceStatus (Fdt, "gwdt@e0bb0000", IsRevB1);
+#if DO_KCS
+ SetDeviceStatus (Fdt, "kcs@e0010000", IsRevB1);
+#else
+ SetDeviceStatus (Fdt, "kcs@e0010000", FALSE);
+#endif
+
+ if (!PcdGetBool (PcdEnableSmmus)) {
+ DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000");
+ DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000");
+ }
+
+ if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) {
+ DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000");
+ }
+
+#if DO_XGBE
+ DisableXgbeSmmus = !PcdGetBool (PcdEnableSmmus);
+#else
+ DisableXgbeSmmus = TRUE;
+#endif
+
+ if (DisableXgbeSmmus) {
+ DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000");
+ DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000");
+ }
+}
+
+STATIC
+VOID
+SetXgbeStatus (
+ IN VOID *Fdt
+ )
+{
+#if DO_XGBE
+ SetDeviceStatus (Fdt, "xgmac@e0700000", TRUE);
+ SetDeviceStatus (Fdt, "phy@e1240800", TRUE);
+ SetDeviceStatus (Fdt, "xgmac@e0900000", TRUE);
+ SetDeviceStatus (Fdt, "phy@e1240c00", TRUE);
+
+ SetMacAddress (Fdt, "xgmac@e0700000", PcdGet64 (PcdEthMacA));
+ SetMacAddress (Fdt, "xgmac@e0900000", PcdGet64 (PcdEthMacB));
+#else
+ SetDeviceStatus (Fdt, "xgmac@e0700000", FALSE);
+ SetDeviceStatus (Fdt, "phy@e1240800", FALSE);
+ SetDeviceStatus (Fdt, "xgmac@e0900000", FALSE);
+ SetDeviceStatus (Fdt, "phy@e1240c00", FALSE);
+#endif
+}
+
+
+STATIC
+EFI_STATUS
+PrepareFdt (
+ IN OUT VOID *Fdt,
+ IN UINTN FdtSize
+ )
+{
+ EFI_STATUS Status;
+ INT32 Node;
+ INT32 CpuNode;
+ UINTN Index;
+ ARM_CORE_INFO *ArmCoreInfoTable;
+ UINTN ArmCoreCount;
+ INT32 MapNode;
+ INT32 ClusterNode;
+ INT32 PmuNode;
+ PMU_INTERRUPT PmuInt;
+ INT32 Phandle[NUM_CORES];
+ UINT32 ClusterIndex;
+ UINT32 CoreIndex;
+ UINT32 ClusterCount;
+ UINT32 CoresInCluster;
+ UINT32 ClusterId;
+ UINTN MpId;
+ CHAR8 Name[10];
+ AMD_MP_CORE_INFO_PROTOCOL *AmdMpCoreInfoProtocol;
+
+ //
+ // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms.
+ //
+ // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file
+ // in the kernel documentation:
+ // Documentation/devicetree/bindings/arm/cpus.txt
+ //
+ Status = gBS->LocateProtocol (
+ &gAmdMpCoreInfoProtocolGuid,
+ NULL,
+ (VOID **)&AmdMpCoreInfoProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Get pointer to ARM core info table
+ ArmCoreInfoTable = AmdMpCoreInfoProtocol->GetArmCoreInfoTable (&ArmCoreCount);
+ ASSERT (ArmCoreInfoTable != NULL);
+ ASSERT (ArmCoreCount <= NUM_CORES);
+
+ // Get Id from primary CPU
+ MpId = (UINTN)ArmReadMpidr ();
+
+ // Create /pmu node
+ PmuNode = fdt_add_subnode(Fdt, 0, "pmu");
+ if (PmuNode >= 0) {
+ fdt_setprop_string (Fdt, PmuNode, "compatible", "arm,armv8-pmuv3");
+
+ // append PMU interrupts
+ for (Index = 0; Index < ArmCoreCount; Index++) {
+ MpId = (UINTN)GET_MPID (ArmCoreInfoTable[Index].ClusterId,
+ ArmCoreInfoTable[Index].CoreId);
+
+ Status = AmdMpCoreInfoProtocol->GetPmuSpiFromMpId (MpId, &PmuInt.IntId);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "FDT: Error getting PMU interrupt for MpId '0x%x'\n", MpId));
+ return Status;
+ }
+
+ PmuInt.Flag = cpu_to_fdt32 (PMU_INT_FLAG_SPI);
+ PmuInt.IntId = cpu_to_fdt32 (PmuInt.IntId);
+ PmuInt.Type = cpu_to_fdt32 (PMU_INT_TYPE_HIGH_LEVEL);
+ fdt_appendprop (Fdt, PmuNode, "interrupts", &PmuInt, sizeof(PmuInt));
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "FDT: Error creating 'pmu' node\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Create /cpus noide
+ Node = fdt_add_subnode (Fdt, 0, "cpus");
+ if (Node >= 0) {
+ // Configure the 'cpus' node
+ fdt_setprop_string (Fdt, Node, "name", "cpus");
+ fdt_setprop_cell (Fdt, Node, "#address-cells", sizeof (UINTN) / 4);
+ fdt_setprop_cell (Fdt, Node, "#size-cells", 0);
+ } else {
+ DEBUG ((DEBUG_ERROR, "FDT: Error creating 'cpus' node\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Walk the processor table in reverse order for proper listing in FDT
+ //
+ Index = ArmCoreCount;
+ while (Index--) {
+ // Create 'cpu' node
+ AsciiSPrint (Name, sizeof (Name), "CPU%d", Index);
+ CpuNode = fdt_add_subnode (Fdt, Node, Name);
+ if (CpuNode < 0) {
+ DEBUG ((DEBUG_ERROR, "FDT: Error on creating '%a' node\n", Name));
+ return EFI_INVALID_PARAMETER;
+ }
+ Phandle[Index] = fdt_alloc_phandle (Fdt);
+ fdt_setprop_cell (Fdt, CpuNode, "phandle", Phandle[Index]);
+ fdt_setprop_cell (Fdt, CpuNode, "linux,phandle", Phandle[Index]);
+
+ fdt_setprop_string (Fdt, CpuNode, "enable-method", "psci");
+
+ MpId = (UINTN)GET_MPID (ArmCoreInfoTable[Index].ClusterId,
+ ArmCoreInfoTable[Index].CoreId);
+ MpId = cpu_to_fdt64 (MpId);
+ fdt_setprop (Fdt, CpuNode, "reg", &MpId, sizeof (MpId));
+ fdt_setprop_string (Fdt, CpuNode, "compatible", "arm,armv8");
+ fdt_setprop_string (Fdt, CpuNode, "device_type", "cpu");
+ }
+
+ // Create /cpu-map node
+ MapNode = fdt_add_subnode (Fdt, Node, "cpu-map");
+ if (MapNode >= 0) {
+ ClusterIndex = ArmCoreCount - 1;
+ ClusterCount = NumberOfClustersInTable (ArmCoreInfoTable,
+ ArmCoreCount);
+ while (ClusterCount--) {
+ // Create 'cluster' node
+ AsciiSPrint (Name, sizeof (Name), "cluster%d", ClusterCount);
+ ClusterNode = fdt_add_subnode (Fdt, MapNode, Name);
+ if (ClusterNode < 0) {
+ DEBUG ((DEBUG_ERROR, "FDT: Error creating '%a' node\n", Name));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ClusterId = ArmCoreInfoTable[ClusterIndex].ClusterId;
+ CoreIndex = ClusterIndex;
+ CoresInCluster = NumberOfCoresInCluster (ArmCoreInfoTable,
+ ArmCoreCount,
+ ClusterId);
+ while (CoresInCluster--) {
+ // Create 'core' node
+ AsciiSPrint (Name, sizeof (Name), "core%d", CoresInCluster);
+ CpuNode = fdt_add_subnode (Fdt, ClusterNode, Name);
+ if (CpuNode < 0) {
+ DEBUG ((DEBUG_ERROR, "FDT: Error creating '%a' node\n", Name));
+ return EFI_INVALID_PARAMETER;
+ }
+ fdt_setprop_cell (Fdt, CpuNode, "cpu", Phandle[CoreIndex]);
+
+ // iterate to next core in cluster
+ if (CoresInCluster) {
+ do {
+ --CoreIndex;
+ } while (ClusterId != ArmCoreInfoTable[CoreIndex].ClusterId);
+ }
+ }
+
+ // iterate to next cluster
+ if (ClusterCount) {
+ do {
+ --ClusterIndex;
+ } while (ClusterInRange (ArmCoreInfoTable,
+ ArmCoreInfoTable[ClusterIndex].ClusterId,
+ ClusterIndex + 1,
+ ArmCoreCount - 1));
+ }
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR,"FDT: Error creating 'cpu-map' node\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SetSocIdStatus (Fdt);
+ SetXgbeStatus (Fdt);
+
+ // Update the real size of the Device Tree
+ fdt_pack (Fdt);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Return a pool allocated copy of the DTB image that is appropriate for
+ booting the current platform via DT.
+
+ @param[out] Dtb Pointer to the DTB copy
+ @param[out] DtbSize Size of the DTB copy
+
+ @retval EFI_SUCCESS Operation completed successfully
+ @retval EFI_NOT_FOUND No suitable DTB image could be located
+ @retval EFI_OUT_OF_RESOURCES No pool memory available
+
+**/
+EFI_STATUS
+EFIAPI
+DtPlatformLoadDtb (
+ OUT VOID **Dtb,
+ OUT UINTN *DtbSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *OrigDtb;
+ VOID *CopyDtb;
+ UINTN OrigDtbSize;
+ UINTN CopyDtbSize;
+ INT32 Error;
+
+ Status = GetSectionFromAnyFv (&gDtPlatformDefaultDtbFileGuid,
+ EFI_SECTION_RAW, 0, &OrigDtb, &OrigDtbSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Allocate space for the DTB: add a page of slack space to make some room
+ // for our modifications.
+ //
+ CopyDtbSize = OrigDtbSize + EFI_PAGE_SIZE;
+ CopyDtb = AllocatePool (CopyDtbSize);
+ if (CopyDtb == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Error = fdt_open_into (OrigDtb, CopyDtb, CopyDtbSize);
+ if (Error != 0) {
+ //
+ // fdt_open_into() validates the DTB header, so if it fails, the template
+ // is most likely invalid.
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ Status = PrepareFdt (CopyDtb, CopyDtbSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *Dtb = CopyDtb;
+ *DtbSize = CopyDtbSize;
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.inf b/Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.inf
new file mode 100644
index 0000000000..fc8b25c928
--- /dev/null
+++ b/Silicon/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.inf
@@ -0,0 +1,65 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = StyxDtbLoaderLib
+ FILE_GUID = 3874890c-2917-46a6-8711-8fcaee92260a
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DtPlatformDtbLoaderLib|DXE_DRIVER
+
+[Sources]
+ StyxDtbLoaderLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/AMD/Styx/AmdModulePkg/AmdModulePkg.dec
+ Silicon/AMD/Styx/AmdStyx.dec
+
+[LibraryClasses]
+ ArmLib
+ BaseLib
+ DebugLib
+ DxeServicesLib
+ FdtLib
+ MemoryAllocationLib
+ PcdLib
+ PrintLib
+ UefiBootServicesTableLib
+
+[Pcd]
+ gAmdStyxTokenSpaceGuid.PcdSocCpuId
+ gAmdStyxTokenSpaceGuid.PcdEthMacA
+ gAmdStyxTokenSpaceGuid.PcdEthMacB
+ gAmdStyxTokenSpaceGuid.PcdEnableSmmus
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset
+ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment
+ gAmdStyxTokenSpaceGuid.PcdPsciOsSupport
+ gAmdStyxTokenSpaceGuid.PcdTrustedFWSupport
+ gAmdStyxTokenSpaceGuid.PcdSata1PortCount
+
+[Guids]
+ gDtPlatformDefaultDtbFileGuid
+
+[Protocols]
+ gAmdMpCoreInfoProtocolGuid ## CONSUMED
+
+[Depex]
+ gAmdMpCoreInfoProtocolGuid