public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [edk2-platforms PATCH 1/1] Silicon/Marvell/OdysseyPkg: New Marvell Odyssey processor
@ 2023-11-30 15:14 Narinder Dhillon
  2023-12-08 16:37 ` Marcin Wojtas via groups.io
  0 siblings, 1 reply; 2+ messages in thread
From: Narinder Dhillon @ 2023-11-30 15:14 UTC (permalink / raw)
  To: devel; +Cc: quic_llindhol, mw, sbalcerak, Narinder Dhillon

From: Narinder Dhillon <ndhillon@marvell.com>

This patch adds support for Marvell Odyssey processor.

It contains only the very basic elements needed to boot to EDK2 UiApp.
- ARM BL31 firmware component copies EDK2 image into memory, so it is
  always executing from memory
- There is a SMC library to get system information from BL31
- There are drivers to get board configuration details from a device
  tree
- There is no on-chip RTC, a dummy driver is used
- Emulated variable storage is used for now

Signed-off-by: Narinder Dhillon <ndhillon@marvell.com>
---
 Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc    | 216 ++++++++++
 Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf    | 304 +++++++++++++
 .../Drivers/Fdt/FdtClientDxe/FdtClientDxe.c   | 382 ++++++++++++++++
 .../Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf |  43 ++
 .../Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c  | 361 ++++++++++++++++
 .../Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h  | 102 +++++
 .../Fdt/FdtPlatformDxe/FdtPlatformDxe.inf     |  60 +++
 .../Fdt/FdtPlatformDxe/FdtPlatformDxe.uni     | 106 +++++
 .../Drivers/Fdt/FdtPlatformDxe/README.txt     |  69 +++
 .../Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c | 283 ++++++++++++
 .../Marvell/Drivers/Null/RtcNull/RtcNullDxe.c | 281 ++++++++++++
 .../Marvell/Drivers/Null/RtcNull/RtcNullDxe.h |  41 ++
 .../Drivers/Null/RtcNull/RtcNullDxe.inf       |  46 ++
 .../Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c  | 408 ++++++++++++++++++
 .../Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf     |  45 ++
 .../AArch64/ArmPlatformHelper.S               |  86 ++++
 .../Library/ArmPlatformLib/ArmPlatformLib.c   |  79 ++++
 .../Library/ArmPlatformLib/ArmPlatformLib.inf |  55 +++
 .../ArmPlatformLib/ArmPlatformLibMem.c        | 131 ++++++
 Silicon/Marvell/Library/SmcLib/SmcLib.c       | 189 ++++++++
 Silicon/Marvell/Library/SmcLib/SmcLib.inf     |  32 ++
 .../Include/Library/SmcLib.h                  |  71 +++
 .../Include/Protocol/FdtClient.h              | 180 ++++++++
 .../MarvellSiliconPkg/MarvellSiliconPkg.dec   |  19 +
 Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc | 394 +++++++++++++++++
 .../PrePi/AArch64/ModuleEntryPoint.S          | 136 ++++++
 .../ArmPlatformPkg/PrePi/PeiMPCore.inf        | 110 +++++
 .../Override/ArmPlatformPkg/PrePi/PrePi.c     | 238 ++++++++++
 28 files changed, 4467 insertions(+)
 create mode 100644 Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc
 create mode 100644 Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c
 create mode 100644 Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c
 create mode 100644 Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h
 create mode 100644 Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf
 create mode 100644 Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c
 create mode 100644 Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf
 create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S
 create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c
 create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf
 create mode 100644 Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c
 create mode 100644 Silicon/Marvell/Library/SmcLib/SmcLib.c
 create mode 100644 Silicon/Marvell/Library/SmcLib/SmcLib.inf
 create mode 100644 Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h
 create mode 100644 Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h
 create mode 100644 Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc
 create mode 100644 Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
 create mode 100644 Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf
 create mode 100644 Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c

diff --git a/Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc b/Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc
new file mode 100644
index 0000000000..ade2faa8bb
--- /dev/null
+++ b/Platform/Marvell/OdysseyPkg/OdysseyPkg.dsc
@@ -0,0 +1,216 @@
+#/** @file
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  https://spdx.org/licenses
+#
+#  Copyright (C) 2023 Marvell
+#
+#  The main build description file for OdysseyPkg.
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = OdysseyPkg  # PLAT=ody
+  PLATFORM_GUID                  = 7E7000DE-F50F-46AE-9B2C-903225F72B13
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+!ifdef $(EDK2_OUT_DIR) # Custom output directory, e.g. -D EDK2_OUT_DIR=Build/XYZ
+  OUTPUT_DIRECTORY               = $(EDK2_OUT_DIR)
+!else
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+!endif
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Marvell/$(PLATFORM_NAME)/$(PLATFORM_NAME).fdf
+
+# dsc.inc file can be used in case there are different variants/boards of Odyssey family.
+# Per-board additional components shall be defined in exclusive dsc.inc files.
+!include Silicon/Marvell/$(PLATFORM_NAME)/$(PLATFORM_NAME).dsc.inc
+
+[LibraryClasses]
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf   # used by PlatformSmbiosDxe
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf # used by SmcLib
+
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf # used by SpiNorDxe
+
+  # USB Requirements
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf # used by UsbKbDxe
+  RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
+
+[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf # used by BaseBmpSupportLib
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+!endif
+# ShellPkg/Application/Shell/Shell.inf -> UefiShellCommandLib -> OrderedCollectionLib
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf # used by CapsuleApp
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+
+[BuildOptions]
+# GCC will generate code that runs on processors as idicated by -march
+# Single = (append) allows flags appendixes coming from [BuildOptions] defined in specific INFs.
+  GCC:*_*_AARCH64_PLATFORM_FLAGS = -DPLAT=0xBF -march=armv8.2-a -fdiagnostics-color -fno-diagnostics-show-caret
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFixedAtBuild.common]
+
+  # Generic Watchdog
+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x8020000A0000
+  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x8020000B0000
+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|0x1A
+
+  #  BIT0  - Initialization message.<BR>
+  #  BIT1  - Warning message.<BR>
+  #  BIT2  - Load Event message.<BR>
+  #  BIT3  - File System message.<BR>
+  #  BIT6  - Information message.<BR>
+  #  DEBUG_ERROR     0x80000000  // Error
+  # NOTE: Adjust according to needs. See MdePkg.dec for bits definition.
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+
+  # The size of volatile buffer. This buffer is used to store VOLATILE attribute variables.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x00040000
+
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  # Set ARM PCD: Odyssey: up to 80 Neoverse V2 cores (code named Demeter)
+  # Used to setup secondary cores stacks and ACPI PPTT.
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|80
+
+  # Stacks for MPCores in Normal World, Non-Trusted DRAM
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x2E000000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
+
+  # System Memory (40 - 1TB of DRAM)
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00004000000
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x10000000000
+
+  # Size of the region used by UEFI in permanent memory (Reserved 128MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000
+
+  ## PL011 - Serial Terminal
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x87e028000000
+
+  # ARM General Interrupt Controller
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x801000000000
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x801000080000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x801000020000
+
+  # Hardcoded terminal: TTYTERM, NOT defined in UEFI SPEC
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+
+  # UART port Divisor setting based on clock 16.66Mhz and baud 115200
+  gArmPlatformTokenSpaceGuid.PL011UartInteger|9
+  gArmPlatformTokenSpaceGuid.PL011UartFractional|2
+
+[PcdsDynamicDefault.common]
+
+  # Indicates if Variable driver will enable emulated variable NV mode.
+  # Reset by SpiNorDxe driver when SPI is in place and can handle storing EFI Variables.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components]
+
+  #
+  # SEC Phase modules
+  #
+
+  # UEFI is placed in RAM by bootloader
+  Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf {
+    <LibraryClasses>
+      # SoC specific implementation of ArmPlatformLib
+      ArmPlatformLib|Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf
+  }
+
+  #
+  # PEI Phase modules
+  #
+  # PEI phase is skipped. SEC jumps directly to DXE.
+
+  #
+  # Core DXE modules
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  #
+  # DXE Status codes
+  #
+!if $(DEBUG) == 1
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+!endif
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+  }
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!else
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!endif
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+      VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+  }
+
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf
+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  # Produces gEfiFaultTolerantWriteProtocolGuid needed for non-volatile UEFI variable storage.
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+  #
+  # RTC Support
+  Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf
+
+  #
+  # ARM Support
+  #
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
diff --git a/Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf b/Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf
new file mode 100644
index 0000000000..b8822a0340
--- /dev/null
+++ b/Platform/Marvell/OdysseyPkg/OdysseyPkg.fdf
@@ -0,0 +1,304 @@
+#/** @file
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  https://spdx.org/licenses
+#
+#  Copyright (C) 2023 Marvell
+#
+#  The main Flash Description File for OdysseyPkg.
+#**/
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.ODYSSEY_AARCH64_EFI]  # Name must match with FV_PREFIX from bootloader/uefi/Makefile
+BaseAddress   = 0x04000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # UEFI in DRAM + 64MB.
+Size          = 0x01000000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the device (16MiB).
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00001000
+NumBlocks     = 0x1000
+
+# 2.5 M should be enough for all modules
+0x00000000|0x00820000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize          = 0x40
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 16        # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = d248e9b7-9ce3-43a7-868e-70c17c4b3819
+
+  APRIORI DXE {
+    INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf                      # gEfiPcdProtocolGuid
+    INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf                         # gHardwareInterruptProtocolGuid
+    INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf                            # gEfiCpuArchProtocolGuid
+  }
+
+  #
+  # Core DXE modules
+  #
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  # (in OdysseyPkg.dsc.inc)
+
+  #
+  # DXE Status codes
+  #
+!if $(DEBUG) == 1
+  INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+!endif
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  INF Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf
+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  # Produces gEfiFaultTolerantWriteProtocolGuid needed for non-volatile UEFI variable storage.
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+  # RTC Support
+  INF Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf
+
+  #
+  # ARM Support
+  #
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+
+  INF ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
+  INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  INF MdeModulePkg/Application/UiApp/UiApp.inf
+
+  # FV Filesystem
+  INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+
+  # SectionExtraction
+  INF MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf
+
+  #
+  # FDT support
+  #
+  # The UEFI driver is at the end of the list of the driver to be dispatched
+  # after the device drivers (eg: Ethernet) to ensure we have support for them.
+  INF Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
+  INF Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  #
+  # SEC Phase modules
+  #
+  INF Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf
+
+  #
+  # PEI Phase modules
+  #
+  # PEI phase is skipped. SEC jumps directly to DXE.
+
+  #
+  # DXE Phase modules stored in separate LZMA compressed FV.
+  #
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
+    TE  TE Align = Auto                 $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) FIXED {
+    TE     TE Align = Auto              $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) FIXED {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE       TE Align = Auto           $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)"     Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c
new file mode 100644
index 0000000000..aa4f773458
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c
@@ -0,0 +1,382 @@
+/** @file
+*  FDT client driver
+*
+*  Copyright (c) 2016, Cavium Inc. All rights reserved.<BR>
+*  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <libfdt.h>
+
+#include <Guid/FdtHob.h>
+
+#include <Protocol/FdtClient.h>
+
+STATIC VOID  *mDeviceTreeBase;
+
+STATIC
+EFI_STATUS
+GetNodeProperty (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  IN  CONST CHAR8             *PropertyName,
+  OUT CONST VOID              **Prop,
+  OUT UINT32                  *PropSize OPTIONAL
+  )
+{
+  INT32 Len;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Prop != NULL);
+
+  *Prop = fdt_getprop (mDeviceTreeBase, Node, PropertyName, &Len);
+  if (*Prop == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (PropSize != NULL) {
+    *PropSize = Len;
+  }
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SetNodeProperty (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  IN  CONST CHAR8             *PropertyName,
+  IN  CONST VOID              *Prop,
+  IN  UINT32                  PropSize
+  )
+{
+  INT32 Ret;
+
+  ASSERT (mDeviceTreeBase != NULL);
+
+  Ret = fdt_setprop (mDeviceTreeBase, Node, PropertyName, Prop, PropSize);
+  if (Ret != 0) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+FindCompatibleNode (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST CHAR8             *CompatibleString,
+  IN  FDT_HANDLE              PrevNode,
+  OUT FDT_HANDLE              *Node
+  )
+{
+  FDT_HANDLE  Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_node_offset_by_compatible (mDeviceTreeBase, PrevNode, CompatibleString);
+
+  if (Offset < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetOrInsertChosenNode (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  OUT INT32                   *Node
+  )
+{
+  INT32 NewNode;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  NewNode = fdt_path_offset (mDeviceTreeBase, "/chosen");
+
+  if (NewNode < 0) {
+    NewNode = fdt_add_subnode (mDeviceTreeBase, 0, "/chosen");
+  }
+
+  if (NewNode < 0) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *Node = NewNode;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNodeDepth (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  OUT INT32                   *Depth
+)
+{
+  *Depth = fdt_node_depth (mDeviceTreeBase, Node);
+
+  if (*Depth < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetParentNode (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  OUT FDT_HANDLE              *Parent
+)
+{
+  *Parent = fdt_parent_offset (mDeviceTreeBase, Node);
+
+  if (*Parent < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNode (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST CHAR8             *Path,
+  OUT FDT_HANDLE              *Node
+)
+{
+  *Node = fdt_path_offset (mDeviceTreeBase, Path);
+
+  if (*Node < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNodePath (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Node,
+  OUT CHAR8                   *Path,
+  IN  INT32                   Size
+)
+{
+  INT32 Result;
+
+  Result = fdt_get_path (mDeviceTreeBase, Node, Path, Size);
+
+  if (Result < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNodeByPropertyValue (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        StartNode,
+  IN  CHAR8                   *Property,
+  IN  VOID                    *Value,
+  IN  INT32                   Size,
+  OUT FDT_HANDLE              *Node
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_node_offset_by_prop_value (mDeviceTreeBase, StartNode,
+                                          Property, Value,
+                                          Size);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetSubnodeByPropertyValue(
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Parent,
+  IN  CHAR8                   *PropertyName,
+  IN  VOID                    *PropertyValue,
+  IN  INT32                   PropertyLength,
+  OUT FDT_HANDLE              *Node
+)
+{
+  INT32          Offset;
+  CONST VOID     *Property;
+  INT32          Length;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_first_subnode (mDeviceTreeBase, Parent);
+
+  while (Offset > 0) {
+    Property = fdt_getprop (mDeviceTreeBase, Offset, PropertyName, &Length);
+
+    if ((Property != NULL) &&
+        (PropertyLength == Length) &&
+        (CompareMem (Property, PropertyValue, Length) == 0)) {
+      *Node = Offset;
+      return EFI_SUCCESS;
+    }
+
+    Offset = fdt_next_subnode(mDeviceTreeBase, Offset);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+STATIC
+EFI_STATUS
+GetNodeByPHandle (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        PHandle,
+  OUT FDT_HANDLE              *Node
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_node_offset_by_phandle (mDeviceTreeBase, PHandle);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetFirstSubnode (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Parent,
+  OUT FDT_HANDLE              *Node
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_first_subnode (mDeviceTreeBase, Parent);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNextSubnode (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Subnode,
+  OUT FDT_HANDLE              *Next
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Next != NULL);
+
+  Offset = fdt_next_subnode (mDeviceTreeBase, Subnode);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Next = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC FDT_CLIENT_PROTOCOL mFdtClientProtocol = {
+  GetNodeProperty,
+  SetNodeProperty,
+  FindCompatibleNode,
+  GetOrInsertChosenNode,
+  GetNodeDepth,
+  GetParentNode,
+  GetNode,
+  GetNodePath,
+  GetNodeByPropertyValue,
+  GetSubnodeByPropertyValue,
+  GetNodeByPHandle,
+  GetFirstSubnode,
+  GetNextSubnode
+};
+
+EFI_STATUS
+EFIAPI
+InitializeFdtClientDxe (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  VOID              *Hob;
+  VOID              *DeviceTreeBase;
+
+  Hob = GetFirstGuidHob (&gFdtHobGuid);
+
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  DeviceTreeBase = GET_GUID_HOB_DATA (Hob);
+  mDeviceTreeBase = (VOID *)*(UINT64 *)DeviceTreeBase;
+  if (fdt_check_header (mDeviceTreeBase)) {
+    DEBUG ((DEBUG_ERROR, "No DTB found @ 0x%p\n", DeviceTreeBase));
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO, "DTB @ 0x%p\n", mDeviceTreeBase));
+
+  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+                                        &gFdtClientProtocolGuid, &mFdtClientProtocol,
+                                        NULL);
+}
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
new file mode 100644
index 0000000000..23bcf8810f
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
@@ -0,0 +1,43 @@
+## @file
+#  FDT client driver
+#
+#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FdtClientDxe
+  FILE_GUID                      = 9A871B00-1C16-4F61-8D2C-93B6654B5AD6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeFdtClientDxe
+
+[Sources]
+  FdtClientDxe.c
+
+[Packages]
+  Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  FdtLib
+  HobLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gFdtClientProtocolGuid                  ## PRODUCES
+
+[Guids]
+  gFdtHobGuid
+  gFdtTableGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c
new file mode 100644
index 0000000000..8faa135003
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c
@@ -0,0 +1,361 @@
+/** @file
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+  https://spdx.org/licenses
+
+  Copyright (C) 2023 Marvell
+
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+#include "FdtPlatform.h"
+
+#include <PiDxe.h>
+
+#include <Library/PcdLib.h>
+#include <Library/BdsLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/FdtHob.h>
+
+//
+// Internal variables
+//
+
+STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolDumpFdt = {
+    L"dumpfdt",                // Name of the command
+    ShellDynCmdDumpFdtHandler, // Handler
+    ShellDynCmdDumpFdtGetHelp  // GetHelp
+};
+
+STATIC CONST EFI_GUID  mFdtPlatformDxeHiiGuid = {
+                         0x8afa7610, 0x62b1, 0x46aa,
+                         {0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c}
+                         };
+
+EFI_HANDLE mFdtPlatformDxeHiiHandle;
+VOID       *mFdtBlobBase;
+
+EFI_STATUS
+DeleteFdtNode (
+  IN  VOID    *FdtAddr,
+  CONST CHAR8 *NodePath,
+  CONST CHAR8 *Compatible
+)
+{
+  INTN        Offset = -1;
+  INTN        Return;
+
+  if ((NodePath != NULL) && (Compatible != NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (NodePath != NULL) {
+    Offset = fdt_path_offset (FdtAddr, NodePath);
+
+    DEBUG ((DEBUG_INFO, "Offset: %d\n", Offset));
+
+    if (Offset < 0) {
+      DEBUG ((DEBUG_ERROR, "Error getting the device node %a offset: %a\n",
+              NodePath, fdt_strerror (Offset)));
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (Compatible != NULL) {
+    Offset = fdt_node_offset_by_compatible (FdtAddr, -1, Compatible);
+
+    DEBUG ((DEBUG_INFO, "Offset: %d\n", Offset));
+
+    if (Offset < 0) {
+      DEBUG ((DEBUG_ERROR, "Error getting the device node for %a offset: %a\n",
+              Compatible, fdt_strerror (Offset)));
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (Offset >= 0) {
+    Return = fdt_del_node (FdtAddr, Offset);
+
+    DEBUG ((DEBUG_INFO, "Return: %d\n", Return));
+
+    if (Return < 0) {
+      DEBUG ((DEBUG_ERROR, "Error deleting the device node %a: %a\n",
+              NodePath, fdt_strerror (Return)));
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DeleteRtcNode (
+  IN  VOID    *FdtAddr
+  )
+{
+  INT32 Offset, NameLen, Return;
+  BOOLEAN Found;
+  CONST CHAR8 *Name;
+
+  Found = FALSE;
+  for (Offset = fdt_next_node(FdtAddr, 0, NULL);
+    Offset >= 0;
+    Offset = fdt_next_node(FdtAddr, Offset, NULL)) {
+
+    Name = fdt_get_name(FdtAddr, Offset, &NameLen);
+    if (!Name) {
+      continue;
+    }
+
+    if ((Name[0] == 'r') && (Name[1] == 't') && (Name[2] == 'c')) {
+      Found = TRUE;
+      break;
+    }
+  }
+
+  if (Found == TRUE) {
+    Return = fdt_del_node (FdtAddr, Offset);
+
+    if (Return < 0) {
+      DEBUG ((DEBUG_ERROR, "Error deleting the device node %a\n", Name));
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FdtFixup(
+  IN VOID *FdtAddr
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  if (FeaturePcdGet(PcdFixupFdt)) {
+    Status |= DeleteFdtNode (FdtAddr, (CHAR8*)PcdGetPtr (PcdFdtConfigRootNode), NULL);
+
+    // Hide the RTC
+    Status |= DeleteRtcNode (FdtAddr);
+  }
+
+  if (!EFI_ERROR(Status)) {
+    fdt_pack(FdtAddr);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Install the FDT specified by its device path in text form.
+
+  @retval  EFI_SUCCESS            The FDT was installed.
+  @retval  EFI_NOT_FOUND          Failed to locate a protocol or a file.
+  @retval  EFI_INVALID_PARAMETER  Invalid device path.
+  @retval  EFI_UNSUPPORTED        Device path not supported.
+  @retval  EFI_OUT_OF_RESOURCES   An allocation failed.
+**/
+STATIC
+EFI_STATUS
+InstallFdt (
+    VOID
+)
+{
+  EFI_STATUS                          Status;
+  UINTN                               FdtBlobSize;
+  VOID                                *FdtConfigurationTableBase;
+  VOID                                *HobList;
+  EFI_HOB_GUID_TYPE                   *GuidHob;
+
+  //
+  // Get the HOB list.  If it is not present, then ASSERT.
+  //
+  HobList = GetHobList ();
+  ASSERT (HobList != NULL);
+
+  //
+  // Search for FDT GUID HOB.  If it is not present, then
+  // there's nothing we can do. It may not exist on the update path.
+  //
+  GuidHob = GetNextGuidHob (&gFdtHobGuid, HobList);
+  if (GuidHob != NULL) {
+    mFdtBlobBase = (VOID *)*(UINT64 *)(GET_GUID_HOB_DATA (GuidHob));
+    FdtBlobSize = fdt_totalsize((VOID *)mFdtBlobBase);
+
+    //
+    // Ensure that the FDT header is valid and that the Size of the Device Tree
+    // is smaller than the size of the read file
+    //
+    if (fdt_check_header (mFdtBlobBase)) {
+        DEBUG ((DEBUG_ERROR, "InstallFdt() - FDT blob seems to be corrupt\n"));
+        mFdtBlobBase = NULL;
+        Status = EFI_LOAD_ERROR;
+        goto Error;
+    }
+  } else {
+    Status = EFI_NOT_FOUND;
+    goto Error;
+  }
+
+  Status = EFI_SUCCESS;
+
+  if (FeaturePcdGet(PcdPublishFdt)) {
+    FdtConfigurationTableBase = AllocateRuntimeCopyPool (FdtBlobSize, mFdtBlobBase);
+
+    if (FdtConfigurationTableBase == NULL) {
+        goto Error;
+    }
+
+    Status = FdtFixup((VOID*)FdtConfigurationTableBase);
+
+    if (EFI_ERROR (Status)) {
+      FreePool (FdtConfigurationTableBase);
+      goto Error;
+    }
+
+    //
+    // Install the FDT into the Configuration Table
+    //
+    Status = gBS->InstallConfigurationTable (
+                  &gFdtTableGuid,
+                  FdtConfigurationTableBase
+                );
+
+    if (EFI_ERROR (Status)) {
+      FreePool (FdtConfigurationTableBase);
+    }
+  }
+
+Error:
+  return Status;
+}
+
+/**
+  Main entry point of the FDT platform driver.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the present driver
+                            UEFI image.
+  @param[in]  *SystemTable  A pointer to the EFI System table.
+
+  @retval  EFI_SUCCESS           The driver was initialized.
+  @retval  EFI_OUT_OF_RESOURCES  The "End of DXE" event could not be allocated or
+                                 there was not enough memory in pool to install
+                                 the Shell Dynamic Command protocol.
+  @retval  EFI_LOAD_ERROR        Unable to add the HII package.
+
+**/
+EFI_STATUS
+FdtPlatformEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  Handle;
+
+  //
+  // Install the Device Tree from its expected location
+  //
+  Status = InstallFdt ();
+
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register the strings for the user interface in the HII Database.
+  // This shows the way to the multi-language support, even if
+  // only the English language is actually supported. The strings to register
+  // are stored in the "ShellSetFdtStrings[]" array. This array is
+  // built by the building process from the "*.uni" file associated to
+  // the present driver (cf. FdtPlatfromDxe.inf). Examine your Build
+  // folder under your package's DEBUG folder and you will find the array
+  // defined in a xxxStrDefs.h file.
+  //
+  mFdtPlatformDxeHiiHandle = HiiAddPackages (
+                                &mFdtPlatformDxeHiiGuid,
+                                ImageHandle,
+                                FdtPlatformDxeStrings,
+                                NULL
+                                );
+  if (mFdtPlatformDxeHiiHandle != NULL) {
+    // We install dynamic EFI command on separate handles as we cannot register
+    // more than one protocol of the same protocol interface on the same handle.
+    Handle = NULL;
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &Handle,
+                    &gEfiShellDynamicCommandProtocolGuid,
+                    &mShellDynCmdProtocolDumpFdt,
+                    NULL
+                    );
+    if (EFI_ERROR (Status)) {
+      HiiRemovePackages (mFdtPlatformDxeHiiHandle);
+    }
+  } else {
+    Status = EFI_LOAD_ERROR;
+  }
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_WARN,
+      "Unable to install \"dumpfdt\" EFI Shell command - %r \n",
+      Status
+      ));
+  }
+
+  return Status;
+}
+
+/**
+  Transcode one of the EFI return code used by the model into an EFI Shell return code.
+
+  @param[in]  Status  EFI return code.
+
+  @return  Transcoded EFI Shell return code.
+
+**/
+SHELL_STATUS
+EfiCodeToShellCode (
+  IN EFI_STATUS  Status
+  )
+{
+  SHELL_STATUS  ShellStatus;
+
+  switch (Status) {
+  case EFI_SUCCESS :
+    ShellStatus = SHELL_SUCCESS;
+    break;
+
+  case EFI_INVALID_PARAMETER :
+    ShellStatus = SHELL_INVALID_PARAMETER;
+    break;
+
+  case EFI_UNSUPPORTED :
+    ShellStatus = SHELL_UNSUPPORTED;
+    break;
+
+  case EFI_DEVICE_ERROR :
+    ShellStatus = SHELL_DEVICE_ERROR;
+    break;
+
+  case EFI_WRITE_PROTECTED    :
+  case EFI_SECURITY_VIOLATION :
+    ShellStatus = SHELL_ACCESS_DENIED;
+    break;
+
+  case EFI_OUT_OF_RESOURCES :
+    ShellStatus = SHELL_OUT_OF_RESOURCES;
+    break;
+
+  case EFI_NOT_FOUND :
+    ShellStatus = SHELL_NOT_FOUND;
+    break;
+
+  default :
+    ShellStatus = SHELL_ABORTED;
+  }
+
+  return ShellStatus;
+}
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h
new file mode 100644
index 0000000000..22517b6d28
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h
@@ -0,0 +1,102 @@
+/** @file
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+  https://spdx.org/licenses
+
+  Copyright (C) 2023 Marvell
+
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+#ifndef __FDT_PLATFORM_DXE_H__
+#define __FDT_PLATFORM_DXE_H__
+
+#include <Uefi.h>
+
+#include <Library/DevicePathLib.h>
+#include <Protocol/Shell.h>
+#include <Protocol/ShellDynamicCommand.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Guid/Fdt.h>
+
+#include <libfdt.h>
+
+extern EFI_HANDLE mFdtPlatformDxeHiiHandle;
+
+/**
+  Transcode one of the EFI return code used by the model into an EFI Shell return code.
+
+  @param[in]  Status  EFI return code.
+
+  @return  Transcoded EFI Shell return code.
+
+**/
+SHELL_STATUS
+EfiCodeToShellCode (
+  IN EFI_STATUS  Status
+  );
+
+/**
+  Run the FDT installation process.
+
+  Loop in priority order over the device paths from which the FDT has
+  been asked to be retrieved for. For each device path, try to install
+  the FDT. Stop as soon as an installation succeeds.
+
+  @param[in]  SuccessfullDevicePath  If not NULL, address where to store the
+                                     pointer to the text device path from
+                                     which the FDT was successfully retrieved.
+                                     Not used if the FDT installation failed.
+                                     The returned address is the address of
+                                     an allocated buffer that has to be
+                                     freed by the caller.
+
+  @retval  EFI_SUCCESS            The FDT was installed.
+  @retval  EFI_NOT_FOUND          Failed to locate a protocol or a file.
+  @retval  EFI_INVALID_PARAMETER  Invalid device path.
+  @retval  EFI_UNSUPPORTED        Device path not supported.
+  @retval  EFI_OUT_OF_RESOURCES   An allocation failed.
+
+**/
+EFI_STATUS
+RunFdtInstallation (
+  OUT CHAR16  **SuccessfullDevicePath
+  );
+
+SHELL_STATUS
+EFIAPI
+ShellDynCmdDumpFdtHandler (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN EFI_SYSTEM_TABLE                    *SystemTable,
+  IN EFI_SHELL_PARAMETERS_PROTOCOL       *ShellParameters,
+  IN EFI_SHELL_PROTOCOL                  *Shell
+  );
+
+/**
+  This is the shell command "dumpfdt" help handler function. This
+  function returns the formatted help for the "dumpfdt" command.
+  The format matchs that in Appendix B of the revision 2.1 of the
+  UEFI Shell Specification.
+
+  @param[in]  This      The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  Language  The pointer to the language string to use.
+
+  @return  CHAR16*  Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdDumpFdtGetHelp (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN CONST CHAR8                         *Language
+  );
+
+#endif /* __FDT_PLATFORM_DXE_H__ */
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
new file mode 100644
index 0000000000..1c3496d13f
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
@@ -0,0 +1,60 @@
+#/** @file
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  https://spdx.org/licenses
+#
+#  Copyright (C) 2023 Marvell
+#
+#  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+#
+#**/
+
+[Defines]
+  INF_VERSION     = 0x00010006
+  BASE_NAME       = FdtPlatformDxe
+  MODULE_UNI_FILE = FdtPlatformDxe.uni
+  FILE_GUID       = 6e9a4c69-57c6-4fcd-b083-4f2c3bdb6051
+  MODULE_TYPE     = UEFI_DRIVER
+  VERSION_STRING  = 0.1
+  ENTRY_POINT     = FdtPlatformEntryPoint
+
+[Sources.common]
+  FdtPlatform.c
+  FdtPlatformDxe.uni
+  ShellDumpFdt.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/ARM/ARM.dec
+  Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  FdtLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  HiiLib
+  ShellLib
+  HobLib
+
+[Protocols]
+  gEfiShellDynamicCommandProtocolGuid
+
+[Guids]
+  gFdtHobGuid
+  gFdtTableGuid
+
+[FeaturePcd]
+  gMarvellSiliconTokenSpaceGuid.PcdPublishFdt
+  gMarvellSiliconTokenSpaceGuid.PcdFixupFdt
+
+[FixedPcd]
+  gMarvellSiliconTokenSpaceGuid.PcdFdtConfigRootNode
+
+[Depex]
+  TRUE
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni
new file mode 100644
index 0000000000..828fb9a609
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni
@@ -0,0 +1,106 @@
+// *++
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+// https://spdx.org/licenses
+//
+// Copyright (C) 2023 Marvell
+//
+// Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+//
+//
+// Module Name:
+//
+//   FdtPlatformDxe
+//
+// Abstract:
+//
+//   String definitions for the EFI Shell 'setfdt' command
+//
+// Revision History:
+//
+// --*/
+
+/=#
+
+#langdef   en-US "English"
+
+#string STR_SETFDT_INSTALLING          #language en-US  "Installing the FDT ...\r\n"
+#string STR_SETFDT_INSTALL_SUCCEEDED   #language en-US  "Installation of\r\n'%s'\r\ncompleted.\r\n"
+
+#string STR_SETFDT_UPDATING            #language en-US  "Updating the FDT device path ...\r\n"
+#string STR_SETFDT_UPDATE_SUCCEEDED    #language en-US  "Update of the FDT device path '%s' completed.\r\n"
+#string STR_SETFDT_UPDATE_DELETED      #language en-US  "The UEFI variable "Fdt" was deleted.\r\n"
+
+#string STR_SETFDT_INVALID_DEVICE_PATH #language en-US  "Invalid device path.\r\n"
+#string STR_SETFDT_INVALID_PATH        #language en-US  "The EFI Shell or device file path '%s' is invalid.\r\n"
+#string STR_SETFDT_ERROR               #language en-US  "Error - %r.\r\n"
+#string STR_SETFDT_DEVICE_PATH_LIST    #language en-US  "FDT device paths :\r\n"
+#string STR_SETFDT_DEVICE_PATH         #language en-US  "'%s'\r\n"
+
+#string STR_GET_HELP_SETFDT            #language en-US ""
+".TH setfdt 0 "Define and/or install a new Flat Device Tree (FDT) for the platform."\r\n"
+".SH NAME\r\n"
+"Define and/or re-install a Flat Device Tree (FDT)\r\n"
+".SH SYNOPSIS\r\n"
+"setfdt [-i] [fdt_path]\r\n"
+".SH OPTIONS\r\n"
+"-i         run the FDT installation process\r\n"
+"file_path  EFI Shell file path or device path to a FDT\r\n"
+"\r\n"
+".SH DESCRIPTION\r\n"
+"NOTES:\r\n"
+"1. If a valid EFI Shell file path is passed to the command, then the\r\n"
+"   command translates the EFI Shell file path into a device path in the\r\n"
+"   text form and saves it in the non volatile UEFI variable "Fdt". If\r\n"
+"   the path to the FDT is a device path in the text form, it is saved as\r\n"
+"   it is in the non volatile UEFI variable "Fdt". The next time the FDT\r\n"
+"   installation process is run, it will first try to install the FDT from\r\n"
+"   the device path specified by the UEFI variable "Fdt".\r\n"
+" \r\n
+"2. If the option -i is passed to the command, then the FDT installation\r\n"
+"   process is run. If a path to the FDT is passed to the command as well,\r\n"
+"   the update of the "Fdt" UEFI variable is done first before to launch\r\n"
+"   the FDT installation process.\r\n"
+" \r\n
+".SH RETURNVALUES\r\n"
+"SHELL_SUCCESS            Operation(s) completed.\r\n"
+"SHELL_ABORTED            Operation aborted.\r\n"
+"SHELL_INVALID_PARAMETER  Invalid argument(s).\r\n"
+"SHELL_NOT_FOUND          Failed to locate a protocol or a file.\r\n"
+"SHELL_UNSUPPORTED        Device path not supported.\r\n"
+"SHELL_OUT_OF_RESOURCES   A memory allocation failed.\r\n"
+"SHELL_DEVICE ERROR       Hardware failure.\r\n"
+"SHELL_ACCESS_DENIED      Access to the Fdt UEFI variable for modification denied.\r\n"
+".SH EXAMPLES\r\n"
+"EXAMPLES:\r\n"
+"1. Relaunch the FDT installation process :\r\n"
+"   Shell> setfdt -i\r\n"
+"   \r\n"
+"2. Set the EFI Shell file path 'fs0:\>fdt.dtb' to be the default path\r\n"
+"   to the FDT :\r\n"
+"   Shell> setfdt fs0:fdt.dtb\r\n"
+"   \r\n"
+"3. Set a TFTP device path to be the default path to the FDT :\r\n"
+"   Shell> setfdt MAC(0002f700570b,0x1)/IPv4(192.168.1.1)/fdt.dtb\r\n"
+"     where . 00:02:f7:00:57:0b is the MAC address of the network\r\n"
+"             interface card to be used. The 'ifconfig -l' EFI Shell\r\n"
+"             command allows to get the MAC address of the network\r\n"
+"             interface cards.\r\n"
+"           . 192.168.1.1 is the address of the TFTP server.\r\n"
+"           . fdt.dtb is the file path to the FDT file on the server.\r\n"
+"4. Display the FDT device paths from the highest to the lowest\r\n"
+"   priority :\r\n"
+"   Shell> setfdt\r\n"
+"5. Delete the "Fdt" UEFI variable :\r\n"
+"   Shell> setfdt ""\r\n"
+"\r\n"
+
+#string STR_GET_HELP_DUMPFDT            #language en-US ""
+".TH dumpfdt 0 "Dump installed Flat Device Tree (FDT) of the platform."\r\n"
+".SH NAME\r\n"
+"Dump current Flat Device Tree (FDT)\r\n"
+".SH SYNOPSIS\r\n"
+"dumpfdt\r\n"
+"\r\n"
+".SH DESCRIPTION\r\n"
+"\r\n"
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt
new file mode 100644
index 0000000000..fe0ee0ba1b
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt
@@ -0,0 +1,69 @@
+/** @file
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+  https://spdx.org/licenses
+
+  Copyright (C) 2023 Marvell
+
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+The purpose of the FdtPlatformDxe UEFI driver is to install the Flat Device
+Tree (FDT) of the platform the UEFI frimware is running on into the UEFI
+Configuration Table. The FDT is identified within the UEFI Configuration
+Table by the "gFdtTableGuid" GUID defined in "EmbeddedPkg.dec".
+
+Once installed, an UEFI application or OS boot loader can get from the UEFI
+Configuration Table the FDT of the platform from the "gFdtTableGuid" GUID.
+
+The installation is done after each boot at the end of the DXE phase,
+just before the BDS phase. It is done at the end of the DXE phase to be sure
+that all drivers have been dispatched. That way, all UEFI protocols that may
+be needed to retrieve the FDT can be made available. It is done before the BDS
+phase to be able to provide the FDT during that phase.
+
+The present driver tries to retrieve the FDT from the device paths defined in the
+"gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths" PCD. The "PcdFdtDevicePaths" PCD
+contains a list a device paths. The device paths are in the text form and
+separated by semi-colons. The present driver tries the device paths in the order
+it finds them in the "PcdFdtDevicePaths" PCD as long as he did not install
+succesfully a FDT.
+
+The "PcdFdtDevicePaths" PCD is a dynamic PCD that can be modified during the
+DXE phase. This allows for exemple to select the right FDT when a binary is
+intended to run on several platforms and/or variants of a platform.
+
+If the driver manages to download a FDT from one of the device paths mentioned
+above then it installs it in the UEFI Configuration table and the run over the
+device paths is stopped.
+
+For development purposes only, if the feature PCD "gEmbeddedTokenSpaceGuid.
+PcdOverridePlatformFdt" is equal to TRUE, then before to try to install the
+FDT from the device paths listed in the "PcdFdtDevicePaths" PCD, the present
+driver tries to install it using the device path defined by the UEFI variable
+"Fdt". If the variable does not exist or the installation using the device path
+defined by the UEFI variable fails then the installation proceeds as described
+above.
+
+Furthermore and again for development purposes only, if the feature PCD
+"PcdOverridePlatformFdt" is equal to TRUE, the current driver provides the EFI
+Shell command "setfdt" to define the location of the FDT by the mean of an EFI
+Shell file path (like "fs2:\boot\fdt.dtb") or a device path.
+
+If the path passed in to the command is a valid EFI Shell file path, the
+command translates it into the corresponding device path and stores that
+device path in the "Fdt" UEFI variable asking for the variable to be non
+volatile.
+
+If the path passed in to the command is not recognised as a valid EFI
+Shell device path, the command handles it as device path and stored
+in the "Fdt" UEFI variable as it is.
+
+Finally, the "-i" option of the "setfdt" command allows to trigger the FDT
+installation process. The installation process is completed when the command
+returns. The command can be invoked with the "-i" option only and in that
+case the "Fdt" UEFI variable is not updated and the command just runs the
+FDT installation process. If the command is invoked with the "-i" option and
+an EFI Shell file path then first the "Fdt" UEFI variable is updated accordingly
+and then the FDT installation process is run.
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c
new file mode 100644
index 0000000000..cf570b1576
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c
@@ -0,0 +1,283 @@
+/** @file
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+  https://spdx.org/licenses
+
+  Copyright (C) 2023 Marvell
+
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+#include "FdtPlatform.h"
+
+extern VOID       *mFdtBlobBase;
+
+#define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))
+#define PALIGN(p, a)    ((void *)(ALIGN ((unsigned long)(p), (a))))
+#define GET_CELL(p)     (p += 4, *((const uint32_t *)(p-4)))
+
+STATIC
+UINTN
+IsPrintableString (
+  IN CONST VOID* data,
+  IN UINTN len
+  )
+{
+  CONST CHAR8 *s = data;
+  CONST CHAR8 *ss;
+
+  // Zero length is not
+  if (len == 0) {
+    return 0;
+  }
+
+  // Must terminate with zero
+  if (s[len - 1] != '\0') {
+    return 0;
+  }
+
+  ss = s;
+  while (*s/* && isprint (*s)*/) {
+    s++;
+  }
+
+  // Not zero, or not done yet
+  if (*s != '\0' || (s + 1 - ss) < len) {
+    return 0;
+  }
+
+  return 1;
+}
+
+STATIC
+VOID
+PrintData (
+  IN CONST CHAR8* data,
+  IN UINTN len
+  )
+{
+  UINTN i;
+  CONST CHAR8 *p = data;
+
+  // No data, don't print
+  if (len == 0)
+    return;
+
+  if (IsPrintableString (data, len)) {
+    Print (L" = \"%a\"", (const char *)data);
+  } else if ((len % 4) == 0) {
+    Print (L" = <");
+    for (i = 0; i < len; i += 4) {
+      Print (L"0x%08x%a", fdt32_to_cpu (GET_CELL (p)), i < (len - 4) ? " " : "");
+    }
+    Print (L">");
+  } else {
+    Print (L" = [");
+    for (i = 0; i < len; i++)
+      Print (L"%02x%a", *p++, i < len - 1 ? " " : "");
+    Print (L"]");
+  }
+}
+
+STATIC
+VOID
+DumpFdt (
+  IN VOID*                FdtBlob
+  )
+{
+  struct fdt_header *bph;
+  UINT32 off_dt;
+  UINT32 off_str;
+  CONST CHAR8* p_struct;
+  CONST CHAR8* p_strings;
+  CONST CHAR8* p;
+  CONST CHAR8* s;
+  CONST CHAR8* t;
+  UINT32 tag;
+  UINTN sz;
+  UINTN depth;
+  UINTN shift;
+  UINT32 version;
+
+  {
+    // Can 'memreserve' be printed by below code?
+    INTN num = fdt_num_mem_rsv (FdtBlob);
+    INTN i, err;
+    UINT64 addr = 0, size = 0;
+
+    for (i = 0; i < num; i++) {
+      err = fdt_get_mem_rsv (FdtBlob, i, &addr, &size);
+      if (err) {
+        DEBUG ((DEBUG_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i));
+      }
+      else {
+        Print (L"/memreserve/ \t0x%lx \t0x%lx;\n", addr, size);
+      }
+    }
+  }
+
+  depth = 0;
+  shift = 4;
+
+  bph = FdtBlob;
+  off_dt = fdt32_to_cpu (bph->off_dt_struct);
+  off_str = fdt32_to_cpu (bph->off_dt_strings);
+  p_struct = (CONST CHAR8*)FdtBlob + off_dt;
+  p_strings = (CONST CHAR8*)FdtBlob + off_str;
+  version = fdt32_to_cpu (bph->version);
+
+  p = p_struct;
+  while ((tag = fdt32_to_cpu (GET_CELL (p))) != FDT_END) {
+    if (tag == FDT_BEGIN_NODE) {
+      s = p;
+      p = PALIGN (p + AsciiStrLen (s) + 1, 4);
+
+      if (*s == '\0')
+              s = "/";
+
+      Print (L"%*s%a {\n", depth * shift, L" ", s);
+
+      depth++;
+      continue;
+    }
+
+    if (tag == FDT_END_NODE) {
+      depth--;
+
+      Print (L"%*s};\n", depth * shift, L" ");
+      continue;
+    }
+
+    if (tag == FDT_NOP) {
+      /* Print (L"%*s// [NOP]\n", depth * shift, L" "); */
+      continue;
+    }
+
+    if (tag != FDT_PROP) {
+      Print (L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag);
+      break;
+    }
+    sz = fdt32_to_cpu (GET_CELL (p));
+    s = p_strings + fdt32_to_cpu (GET_CELL (p));
+    if (version < 16 && sz >= 8)
+            p = PALIGN (p, 8);
+    t = p;
+
+    p = PALIGN (p + sz, 4);
+
+    Print (L"%*s%a", depth * shift, L" ", s);
+    PrintData (t, sz);
+    Print (L";\n");
+  }
+}
+
+/**
+  This is the shell command "dumpfdt" handler function. This function handles
+  the command when it is invoked in the shell.
+
+  @param[in]  This             The instance of the
+                               EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  SystemTable      The pointer to the UEFI system table.
+  @param[in]  ShellParameters  The parameters associated with the command.
+  @param[in]  Shell            The instance of the shell protocol used in the
+                               context of processing this command.
+
+  @return  SHELL_SUCCESS            The operation was successful.
+  @return  SHELL_ABORTED            Operation aborted due to internal error.
+  @return  SHELL_NOT_FOUND          Failed to locate the Device Tree into the EFI Configuration Table
+  @return  SHELL_OUT_OF_RESOURCES   A memory allocation failed.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdDumpFdtHandler (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN EFI_SYSTEM_TABLE                    *SystemTable,
+  IN EFI_SHELL_PARAMETERS_PROTOCOL       *ShellParameters,
+  IN EFI_SHELL_PROTOCOL                  *Shell
+  )
+{
+  SHELL_STATUS  ShellStatus;
+  EFI_STATUS    Status;
+  VOID          *FdtBlob;
+
+  ShellStatus  = SHELL_SUCCESS;
+
+  //
+  // Install the Shell and Shell Parameters Protocols on the driver
+  // image. This is necessary for the initialisation of the Shell
+  // Library to succeed in the next step.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &gImageHandle,
+                  &gEfiShellProtocolGuid, Shell,
+                  &gEfiShellParametersProtocolGuid, ShellParameters,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    return SHELL_ABORTED;
+  }
+
+  //
+  // Initialise the Shell Library as we are going to use it.
+  // Assert that the return code is EFI_SUCCESS as it should.
+  // To anticipate any change is the codes returned by
+  // ShellInitialize(), leave in case of error.
+  //
+  Status = ShellInitialize ();
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return SHELL_ABORTED;
+  }
+
+  if (PcdGetBool (PcdPublishFdt)) {
+    Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob);
+
+    if (EFI_ERROR (Status)) {
+      Print (L"ERROR: Did not find the Fdt Blob.\n");
+      return EfiCodeToShellCode (Status);
+    }
+  } else {
+    FdtBlob = mFdtBlobBase;
+  }
+
+  DumpFdt (FdtBlob);
+
+  gBS->UninstallMultipleProtocolInterfaces (
+         gImageHandle,
+         &gEfiShellProtocolGuid, Shell,
+         &gEfiShellParametersProtocolGuid, ShellParameters,
+         NULL
+         );
+
+  return ShellStatus;
+}
+
+/**
+  This is the shell command "dumpfdt" help handler function. This
+  function returns the formatted help for the "dumpfdt" command.
+  The format matchs that in Appendix B of the revision 2.1 of the
+  UEFI Shell Specification.
+
+  @param[in]  This      The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  Language  The pointer to the language string to use.
+
+  @return  CHAR16*  Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdDumpFdtGetHelp (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN CONST CHAR8                         *Language
+  )
+{
+  //
+  // This allocates memory. The caller has to free the allocated memory.
+  //
+  return HiiGetString (
+                mFdtPlatformDxeHiiHandle,
+                STRING_TOKEN (STR_GET_HELP_DUMPFDT),
+                Language
+                );
+}
diff --git a/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c
new file mode 100644
index 0000000000..caa27a2348
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.c
@@ -0,0 +1,281 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2022 Marvell
+*
+* Source file for NULL RTC Driver
+*
+**/
+
+#include <Uefi.h>                                 // Base defines
+#include <Library/DebugLib.h>                     // DEBUG
+#include <Library/MemoryAllocationLib.h>          // AllocateRuntimeZeroPool
+#include <Library/BaseMemoryLib.h>                // ZeroMem
+#include <Library/UefiBootServicesTableLib.h>     // gBS
+#include <Library/UefiRuntimeLib.h>               // EfiConvertPointer
+#include <Library/UefiRuntimeServicesTableLib.h>  // gRT
+
+#include "RtcNullDxe.h"
+
+// all variables used across the driver
+RTC_NULL_PRIVATE_DATA        *mRtcPrivateData;
+STATIC EFI_EVENT              mRtcVirtualAddressChangeEvent;
+
+STATIC CONST INTN             DayOfMonth[12] =
+                                { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+STATIC
+BOOLEAN
+IsLeapYear(IN EFI_TIME   *Time)
+{
+  if (Time->Year % 4 == 0) {
+    if (Time->Year % 100 == 0) {
+      if (Time->Year % 400 == 0) {
+        return TRUE;
+      } else {
+        return FALSE;
+      }
+    } else {
+      return TRUE;
+    }
+  } else {
+    return FALSE;
+  }
+}
+
+BOOLEAN DayValid(IN  EFI_TIME  *Time)
+{
+  if (Time->Day < 1 ||
+    Time->Day > DayOfMonth[Time->Month - 1] ||
+    (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+EFI_STATUS
+GetDateTime(
+  IN  RTC_NULL_PRIVATE_DATA *PrivateData,
+  OUT EFI_TIME               *Time)
+{
+
+  if (PrivateData == NULL || Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem(Time, sizeof(EFI_TIME));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SetDateTime(IN RTC_NULL_PRIVATE_DATA *PrivateData,
+                  IN EFI_TIME               *Time)
+{
+  if (PrivateData == NULL || Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ( (Time->Month < 1) || (Time->Month > 12) ||
+       (Time->Second > 59) || (Time->Minute > 59) ||
+       (Time->Hour > 23) || (!DayValid(Time)) ||
+       (Time->Year < 1998) || (Time->Year > 2099) ||
+       (Time->Nanosecond > 999999999) ||
+       (Time->TimeZone < -1440) || ((Time->TimeZone > 1440) &&
+         (Time->TimeZone != 2047))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+GetTime(OUT EFI_TIME * Time, OUT EFI_TIME_CAPABILITIES * Capabilities)
+{
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (mRtcPrivateData->Initialized == FALSE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return GetDateTime (mRtcPrivateData, Time);
+}
+
+
+
+/**
+  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 SetTime(IN EFI_TIME * Time)
+{
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (mRtcPrivateData->Initialized == FALSE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return SetDateTime (mRtcPrivateData, Time);
+}
+
+
+/**
+  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
+GetWakeupTime(OUT BOOLEAN * Enabled,
+              OUT BOOLEAN * Pending, OUT EFI_TIME * Time)
+{
+  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 SetWakeupTime(IN BOOLEAN Enabled, OUT EFI_TIME * Time)
+{
+    return EFI_UNSUPPORTED;
+}
+
+
+// Convert the mSmbus as well since the SmbusLib leaves this to the runtine DXEs
+
+EFIAPI VOID
+RtcVirtualNotifyEvent(IN EFI_EVENT Event, IN VOID * Context)
+{
+  EfiConvertPointer (0x0, (VOID **) &mRtcPrivateData);
+}
+
+/**
+  The Entry Point of module. It follows the standard UEFI driver model.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The entry point is executed successfully.
+  @retval other         Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+    EFIAPI
+RtcNullDxeInitialize (
+  IN EFI_HANDLE ImageHandle,
+  IN EFI_SYSTEM_TABLE * SystemTable)
+{
+  EFI_TIME               Time;
+  RTC_NULL_PRIVATE_DATA *Private = NULL;
+  EFI_STATUS             Status = EFI_SUCCESS;
+
+  DEBUG ((DEBUG_INFO, "RtcNullDxeInitialize\n"));
+
+  /* Allocate the private data */
+  Private = AllocateRuntimeZeroPool (sizeof (RTC_NULL_PRIVATE_DATA));
+
+  if (Private == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((DEBUG_ERROR, "RtcDxeInitialize: %r\n", Status));
+    goto Exit;
+  }
+
+  mRtcPrivateData = Private;
+
+  Private->Initialized = FALSE;
+  Private->Bus         = 0xFF;
+  Private->SlaveAddr   = 0xFF;
+
+  /* Check clock and init it to UNIX start time */
+  Status = GetDateTime (mRtcPrivateData, &Time);
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "RtcNullDxeInitialize: %r\n", Status));
+    goto Exit;
+  }
+
+  if (Time.Year == 1900) {
+    Time.Day = 1;
+    Time.Month = 1;
+    Time.Year = 1998;
+    Time.Second = 0;
+    Time.Minute = 0;
+    Time.Hour = 0;
+    Time.Daylight = 0;
+    Time.TimeZone = 0;
+
+    Status = SetDateTime (mRtcPrivateData, &Time);
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "RtcDxeInitialize: %r\n", Status));
+      goto Exit;
+    }
+  }
+
+Exit:
+  gRT->GetTime       = GetTime;
+  gRT->SetTime       = SetTime;
+  gRT->GetWakeupTime = GetWakeupTime;
+  gRT->SetWakeupTime = SetWakeupTime;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (&Private->RtcHandle,
+                                                   &gEfiRealTimeClockArchProtocolGuid,
+                                                   NULL,
+                                                   NULL);
+
+  Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL,
+                               TPL_NOTIFY,
+                               RtcVirtualNotifyEvent,
+                               NULL,
+                               &gEfiEventVirtualAddressChangeGuid,
+                               &mRtcVirtualAddressChangeEvent);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
diff --git a/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h
new file mode 100644
index 0000000000..c8fe54ace3
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.h
@@ -0,0 +1,41 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2022 Marvell
+*
+* Header file for NULL RTC Driver
+*
+**/
+
+#ifndef _RTC_NULL_DXE_H_
+#define _RTC_NULL_DXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+//#include <Library/IoLib.h>
+//#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h> // gBS
+#include <Library/BaseMemoryLib.h>            // ZeroMem
+//#include <Library/UefiLib.h>
+
+
+//
+//  Private data for driver.
+//
+#define RTC_NULL_DXE_PRIVATE_DATA_SIGNATURE  SIGNATURE_32( 'R', 'T', 'C', '_' )
+
+typedef struct {
+    UINT32     Signature;
+    UINT8      Bus;
+    UINT8      SlaveAddr;
+    EFI_HANDLE RtcHandle;
+    BOOLEAN    Initialized;
+} RTC_NULL_PRIVATE_DATA;
+
+
+#endif                          //_RTC_NULL_DXE_H_
diff --git a/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf
new file mode 100644
index 0000000000..d262e971fc
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Null/RtcNull/RtcNullDxe.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  https://spdx.org/licenses
+#
+#  Copyright (C) 2022 Marvell
+#  Module description file of RTC NULL driver.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RtcNullDxe
+  FILE_GUID                      = 9c0a0971-b0f6-442e-ac01-0a3eb52c457d
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = RtcNullDxeInitialize
+
+
+[Sources]
+  RtcNullDxe.c
+  RtcNullDxe.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiRuntimeLib
+  UefiRuntimeServicesTableLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+
+[Protocols]
+  gEfiRealTimeClockArchProtocolGuid      ## PRODUCES
+
+[Depex]
+  TRUE
+
diff --git a/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c
new file mode 100644
index 0000000000..12be08ff24
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdog.c
@@ -0,0 +1,408 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2022 Marvell
+*
+* Source file for Marvell Watchdog driver
+*
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/FdtClient.h>
+#include <Protocol/WatchdogTimer.h>
+
+#define GTI_CWD_WDOG(Core)    (FixedPcdGet64(PcdGtiWatchdogBase64) + 0x40000 + Core * 0x8)
+#define GTI_CWD_POKE(Core)    (FixedPcdGet64(PcdGtiWatchdogBase64) + 0x50000 + Core * 0x8)
+
+typedef union _GTI_CWD_WDOG_UNION {
+  UINT64          U64;
+  struct {
+    UINTN Mode   : 2;
+    UINTN State  : 2;
+    UINTN Len    : 16;
+    UINTN Cnt    : 24;
+    UINTN DStop  : 1;
+    UINTN GStop  : 1;
+    UINTN Rsvd   : 18;
+  } PACKED S;
+} GTI_CWD_WDOG_UNION;
+
+#define CWD_WDOG_MODE_RST     (BIT1 | BIT0)
+
+#define RST_BOOT_PNR_MUL(Val)  ((Val >> 33) & 0x1F)
+
+EFI_EVENT mGtiExitBootServicesEvent = (EFI_EVENT)NULL;
+UINT32  mSclk = 0;
+BOOLEAN mHardwarePlatform = TRUE;
+
+/**
+  Stop the GTI watchdog timer from counting down by disabling interrupts.
+**/
+STATIC
+VOID
+GtiWdtStop (
+  VOID
+  )
+{
+  GTI_CWD_WDOG_UNION Wdog;
+
+  MmioWrite64(GTI_CWD_POKE(0), 0);
+
+  Wdog.U64 = MmioRead64(GTI_CWD_WDOG(0));
+
+  // Disable WDT
+  if (Wdog.S.Mode != 0) {
+    Wdog.S.Len = 1;
+    Wdog.S.Mode = 0;
+    MmioWrite64 (GTI_CWD_WDOG(0), Wdog.U64);
+  }
+}
+
+/**
+  Starts the GTI WDT countdown by enabling interrupts.
+  The count down will start from the value stored in the Load register,
+  not from the value where it was previously stopped.
+**/
+STATIC
+VOID
+GtiWdtStart (
+  VOID
+  )
+{
+  GTI_CWD_WDOG_UNION Wdog;
+
+  // Reset the WDT
+  MmioWrite64 (GTI_CWD_POKE(0), 0);
+
+  Wdog.U64 = MmioRead64 (GTI_CWD_WDOG(0));
+
+  // Enable countdown
+  if (Wdog.S.Mode == 0) {
+    Wdog.S.Mode = CWD_WDOG_MODE_RST;
+    MmioWrite64 (GTI_CWD_WDOG(0), Wdog.U64);
+  }
+}
+
+/**
+    On exiting boot services we must make sure the SP805 Watchdog Timer
+    is stopped.
+**/
+VOID
+EFIAPI
+GtiExitBootServices (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  MmioWrite64 (GTI_CWD_POKE(0), 0);
+  GtiWdtStop ();
+}
+
+/**
+  This function registers the handler NotifyFunction so it is called every time
+  the watchdog timer expires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.
+  If NotifyFunction is not NULL and a handler is not already registered,
+  then the new handler is registered and EFI_SUCCESS is returned.
+  If NotifyFunction is NULL, and a handler is already registered,
+  then that handler is unregistered.
+  If an attempt is made to register a handler when a handler is already registered,
+  then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not registered,
+  then EFI_INVALID_PARAMETER is returned.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  NotifyFunction   The function to call when a timer interrupt fires. This
+                           function executes at TPL_HIGH_LEVEL. The DXE Core will
+                           register a handler for the timer interrupt, so it can know
+                           how much time has passed. This information is used to
+                           signal timer based events. NULL will unregister the handler.
+
+  @retval EFI_SUCCESS           The watchdog timer handler was registered.
+  @retval EFI_ALREADY_STARTED   NotifyFunction is not NULL, and a handler is already
+                                registered.
+  @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
+                                previously registered.
+  @retval EFI_UNSUPPORTED       HW does not support this functionality.
+
+**/
+EFI_STATUS
+EFIAPI
+GtiWdtRegisterHandler (
+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,
+  IN EFI_WATCHDOG_TIMER_NOTIFY                NotifyFunction
+  )
+{
+  // UNSUPPORTED - The hardware watchdog will reset the board
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      The rate to program the timer interrupt in 100 nS units. If
+                           the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                           returned. If the timer is programmable, then the timer period
+                           will be rounded up to the nearest timer period that is supported
+                           by the timer hardware. If TimerPeriod is set to 0, then the
+                           timer interrupts will be disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was changed.
+  @retval EFI_UNSUPPORTED       The platform cannot change the period of the timer interrupt.
+  @retval EFI_DEVICE_ERROR      The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+GtiWdtSetTimerPeriod (
+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,
+  IN UINT64                                   TimerPeriod   // In 100ns units
+  )
+{
+  UINT32             Clock;
+  UINT64             CountDown;
+  GTI_CWD_WDOG_UNION Wdog;
+
+  if (TimerPeriod == 0) {
+
+    // This is a watchdog stop request
+    GtiWdtStop();
+
+    return EFI_SUCCESS;
+  } else {
+    //
+    // The system is reset only after the WDT expires for the 3rd time
+    //
+
+    Clock = mSclk / 1000000; //MHz
+    CountDown = DivU64x32 (MultU64x32 (TimerPeriod, Clock), 30);
+
+    // WDT counts in 1024 cycle steps
+    // Only upper 16 bits can be used
+
+    Wdog.U64   = 0;
+    Wdog.S.Len = (CountDown + (0xFF << 10)) >> 18;
+    MmioWrite64 (GTI_CWD_WDOG(0), Wdog.U64);
+
+    // Start the watchdog
+    if (mHardwarePlatform == TRUE) {
+      GtiWdtStart();
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      A pointer to the timer period to retrieve in 100 ns units. If
+                           0 is returned, then the timer is currently disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GtiWdtGetTimerPeriod (
+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                                  *TimerPeriod
+  )
+{
+  UINT32             Clock;
+  UINT64             CountDown;
+  UINT64             ReturnValue;
+  GTI_CWD_WDOG_UNION Wdog;
+
+  if (TimerPeriod == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Wdog.U64 = MmioRead64 (GTI_CWD_WDOG(0));
+
+  // Check if the watchdog is stopped
+  if (Wdog.S.Mode == 0) {
+    // It is stopped, so return zero.
+    ReturnValue = 0;
+  } else {
+    // Convert the Watchdog ticks into TimerPeriod
+    Clock = mSclk / 1000000; //MHz
+    CountDown = Wdog.S.Len << 18;
+
+    ReturnValue = MultU64x32(DivU64x32(3 * CountDown, Clock), 10); // usecs * 10
+  }
+
+  *TimerPeriod = ReturnValue;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Interface structure for the Watchdog Architectural Protocol.
+
+  @par Protocol Description:
+  This protocol provides a service to set the amount of time to wait
+  before firing the watchdog timer, and it also provides a service to
+  register a handler that is invoked when the watchdog timer fires.
+
+  @par When the watchdog timer fires, control will be passed to a handler
+  if one has been registered.  If no handler has been registered,
+  or the registered handler returns, then the system will be
+  reset by calling the Runtime Service ResetSystem().
+
+  @param RegisterHandler
+  Registers a handler that will be called each time the
+  watchdogtimer interrupt fires.  TimerPeriod defines the minimum
+  time between timer interrupts, so TimerPeriod will also
+  be the minimum time between calls to the registered
+  handler.
+  NOTE: If the watchdog resets the system in hardware, then
+        this function will not have any chance of executing.
+
+  @param SetTimerPeriod
+  Sets the period of the timer interrupt in 100 nS units.
+  This function is optional, and may return EFI_UNSUPPORTED.
+  If this function is supported, then the timer period will
+  be rounded up to the nearest supported timer period.
+
+  @param GetTimerPeriod
+  Retrieves the period of the timer interrupt in 100 nS units.
+
+**/
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL    gWatchdogTimer = {
+  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) GtiWdtRegisterHandler,
+  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) GtiWdtSetTimerPeriod,
+  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) GtiWdtGetTimerPeriod
+};
+
+/**
+  Initialize the state information for the Watchdog Timer Architectural Protocol.
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS           Protocol registered
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+GtiWdtInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  Handle = NULL;
+  FDT_HANDLE  SclkHandle = 0;
+  FDT_HANDLE  RootHandle = 0;
+  CONST UINT32        *SclkFreq = NULL;
+  FDT_CLIENT_PROTOCOL *FdtClient = NULL;
+  CONST CHAR8 *Platform;
+
+  DEBUG ((DEBUG_INFO, "GtiWdtInitialize: Start\n"));
+  // Stop the watchdog from triggering unexpectedly
+  GtiWdtStop ();
+
+  //
+  // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet.
+  // This will avoid conflicts with the universal watchdog
+  //
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
+
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid,
+                                NULL,
+                                (VOID **)&FdtClient);
+
+  if (EFI_ERROR (Status) || (FdtClient == NULL)) {
+    DEBUG ((DEBUG_ERROR, "%a: ERROR: cannot locate: gFdtClientProtocolGuid\n", __func__));
+    return EFI_ABORTED;
+  }
+
+  Status = FdtClient->GetNode (FdtClient, "/soc@0/sclk", &SclkHandle);
+  if (EFI_ERROR (Status) || !SclkHandle) {
+    DEBUG ((DEBUG_ERROR, "%a: %s node not found!\n", __func__, L"/soc@0/sclk"));
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO, "%a: Found: %s\n", __func__, L"/soc@0/sclk"));
+  Status = FdtClient->GetNodeProperty (FdtClient,
+                                        SclkHandle,
+                                        "clock-frequency",
+                                        (CONST VOID **)&SclkFreq,
+                                        NULL);
+  if (EFI_ERROR (Status) || NULL == SclkFreq) {
+    DEBUG ((DEBUG_ERROR, "%a: %s property not found!\n", __func__, L"\"clock-frequency\""));
+    return EFI_NO_MAPPING;
+  }
+
+  mSclk = FdtToCpu32(*SclkFreq);
+  DEBUG ((DEBUG_INFO, "%a: DT sclk = %d Mhz (0x%x)\n", __func__, mSclk/1000000, mSclk));
+
+  Status = FdtClient->GetNode (FdtClient, "/soc@0", &RootHandle);
+  if (!EFI_ERROR (Status) && RootHandle) {
+    Status = FdtClient->GetNodeProperty (FdtClient,
+                                        RootHandle,
+                                        "runplatform",
+                                        (CONST VOID **)&Platform,
+                                        NULL);
+    if (!EFI_ERROR (Status)) {
+      if (AsciiStrCmp (Platform, "HW_PLATFORM")) {
+        mHardwarePlatform = FALSE;
+        DEBUG ((DEBUG_INFO, "%a: Not a hardware platform\n", __func__));
+      }
+    }
+  }
+
+  // Register for an ExitBootServicesEvent
+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES,
+                             TPL_NOTIFY,
+                             GtiExitBootServices,
+                             NULL,
+                             &mGtiExitBootServicesEvent);
+  ASSERT_EFI_ERROR(Status);
+
+  // Install the Timer Architectural Protocol onto a new handle
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces(
+                  &Handle,
+                  &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "GtiWdtInitialize: Exit\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf
new file mode 100644
index 0000000000..f9aa4da246
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Wdt/GtiWatchdogDxe/GtiWatchdogDxe.inf
@@ -0,0 +1,45 @@
+#/** @file
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  https://spdx.org/licenses
+#
+#  Copyright (C) 2022 Marvell
+#
+#  Module definition file for Marvell Watchdog driver.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GtiWatchdogDxe
+  FILE_GUID                      = 789F5711-6FD3-4170-BE11-EE4000037EA8
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = GtiWdtInitialize
+
+[Sources.common]
+  GtiWatchdog.c
+
+[Packages]
+  Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[FixedPcd]
+  gMarvellSiliconTokenSpaceGuid.PcdGtiWatchdogBase64
+
+[Protocols]
+  gEfiWatchdogTimerArchProtocolGuid   #PRODUCES
+  gFdtClientProtocolGuid              #CONSUMED
+
+[Depex]
+  gFdtClientProtocolGuid
diff --git a/Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S b/Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S
new file mode 100644
index 0000000000..757c032f84
--- /dev/null
+++ b/Silicon/Marvell/Library/ArmPlatformLib/AArch64/ArmPlatformHelper.S
@@ -0,0 +1,86 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2023 Marvell
+*
+* Source file for Marvell ARM Platform library
+* Based on ArmPlatformPkg/Library/ArmPlatformLibNull
+**/
+
+#include <AsmMacroIoLibV8.h>
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+#include <Library/SmcLib.h>
+
+/* x1 - node number
+ */
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
+
+GCC_ASM_IMPORT(mSystemMemoryEnd)
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  adr   x1, PrimaryCoreMpid
+  str   w0, [x1]
+  ldr   x0, =MV_SMC_ID_DRAM_SIZE
+  mov   x1, xzr
+  smc   #0
+  sub   x0, x0, #1           // Last valid address
+  adr   x1, mSystemMemoryEnd
+  str   x0, [x1]             // Set mSystemMemoryEnd
+
+  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
+  mov   x0, #1
+  mov   x1, #0
+  csel  x0, x0, x1, eq
+  ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformGetCorePosition)
+/*
+  Affinity Level 0: single thread 0
+  Affinity Level 1: clustering 0(
+  Affinity Level 2: number of clusters up to 64 (CN10K)/ 80 (Odyssey)/ 16 (Iliad)
+  Affinity Level 3: number of chip 0
+  LinearId = Aff2
+*/
+  and   x0, x0, #ARM_CORE_AFF2
+  lsr   x0, x0, #16
+  ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
+
+PrimaryCoreMpid:  .word    0x0
diff --git a/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c
new file mode 100644
index 0000000000..ed48a00950
--- /dev/null
+++ b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.c
@@ -0,0 +1,79 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2022 Marvell
+*
+* Source file for Marvell ARM Platform library
+* Based on ArmPlatformPkg/Library/ArmPlatformLibNull
+**/
+
+#include <Uefi.h>
+#include <Pi/PiBootMode.h>          // EFI_BOOT_MODE
+#include <Pi/PiPeiCis.h>            // EFI_PEI_PPI_DESCRIPTOR
+#include <Library/DebugLib.h>       // ASSERT
+#include <Library/ArmPlatformLib.h> // ArmPlatformIsPrimaryCore
+#include <Ppi/ArmMpCoreInfo.h>      // ARM_MP_CORE_INFO_PPI
+
+/**
+  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/PrePei or ArmPlatformPkg/Pei/PlatformPeim
+  in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  ASSERT(ArmPlatformIsPrimaryCore (MpId));
+
+  return RETURN_SUCCESS;
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN                   *CoreCount,
+  OUT ARM_CORE_INFO           **ArmCoreTable
+  )
+{
+    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
+  )
+{
+  *PpiListSize = sizeof(gPlatformPpiTable);
+  *PpiList = gPlatformPpiTable;
+}
diff --git a/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf
new file mode 100644
index 0000000000..1a4b81adb4
--- /dev/null
+++ b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLib.inf
@@ -0,0 +1,55 @@
+#/** @file
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+# https://spdx.org/licenses
+#
+# Copyright (C) 2022 Marvell
+#
+# Marvell ARM Platform library
+# Based on ArmPlatformPkg/Library/ArmPlatformLibNull
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmPlatformLib
+  FILE_GUID                      = 7ea0f45b-0e06-4e45-8353-9c28b091a11c
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec # Include ArmPlatformLib.h
+  Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  HobLib
+  DebugLib
+  MemoryAllocationLib
+  SmcLib
+
+[Sources]
+  ArmPlatformLib.c
+  ArmPlatformLibMem.c
+
+[Sources.AARCH64]
+  AArch64/ArmPlatformHelper.S
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+  gMarvellSiliconTokenSpaceGuid.PcdNodeDramBase
+  gMarvellSiliconTokenSpaceGuid.PcdIoBaseAddress
+  gMarvellSiliconTokenSpaceGuid.PcdNodeIoBaseAddress
+  gMarvellSiliconTokenSpaceGuid.PcdIoSize
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
diff --git a/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c
new file mode 100644
index 0000000000..1626dea6c5
--- /dev/null
+++ b/Silicon/Marvell/Library/ArmPlatformLib/ArmPlatformLibMem.c
@@ -0,0 +1,131 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2022 Marvell
+*
+* Source file for Marvell ARM Platform library
+* Based on ArmPlatformPkg/Library/ArmPlatformLibNull
+**/
+
+#include <Uefi.h>                         // Basic UEFI types
+#include <Library/DebugLib.h>             // DEBUG
+#include <Pi/PiBootMode.h>                // EFI_BOOT_MODE required by PiHob.h
+#include <Pi/PiHob.h>                     // EFI_RESOURCE_ATTRIBUTE_TYPE
+#include <Library/HobLib.h>               // BuildResourceDescriptorHob
+#include <Library/PcdLib.h>               // PcdGet64
+#include <Library/ArmLib.h>               // ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#include <Library/SmcLib.h>               // SmcGetRamSize
+#include <Library/MemoryAllocationLib.h>  // AllocatePages
+
+// Number of Virtual Memory Map Descriptors
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          129
+#define MAX_NODES                                   1
+
+// 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;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  UINT64                        VirtualMemoryTableSize;
+  UINT64                        MemoryBase;
+  UINT64                        MemorySize;
+  UINTN                         Index = 0;
+  UINTN                         Node;
+  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTableSize = sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS;
+  VirtualMemoryTable = AllocatePages (EFI_SIZE_TO_PAGES (VirtualMemoryTableSize));
+
+  if (VirtualMemoryTable == NULL) {
+      return;
+  }
+
+  CacheAttributes = DDR_ATTRIBUTES_CACHED;
+
+  ResourceAttributes =
+        EFI_RESOURCE_ATTRIBUTE_PRESENT |
+        EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+        EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_TESTED;
+
+
+  VirtualMemoryTable[Index].PhysicalBase = PcdGet64(PcdFdBaseAddress);
+  VirtualMemoryTable[Index].VirtualBase  = PcdGet64(PcdFdBaseAddress);
+  VirtualMemoryTable[Index].Length       = PcdGet32(PcdFdSize);
+  VirtualMemoryTable[Index].Attributes   = CacheAttributes;
+  Index++;
+
+  BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+                              ResourceAttributes,
+                              PcdGet64 (PcdFdBaseAddress),
+                              PcdGet32 (PcdFdSize));
+
+  for (Node = 0; Node < MAX_NODES; Node++) {
+      MemoryBase = Node * FixedPcdGet64(PcdNodeDramBase);
+      MemorySize = SmcGetRamSize(Node);
+
+      MemoryBase += (Node == 0) ? PcdGet64(PcdSystemMemoryBase) : 0;
+      MemorySize -= (Node == 0) ? PcdGet64(PcdSystemMemoryBase) : 0;
+
+      BuildResourceDescriptorHob (
+            EFI_RESOURCE_SYSTEM_MEMORY,
+            ResourceAttributes,
+            MemoryBase,
+            MemorySize);
+
+      DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Memory %lx @ %lx\n",  MemorySize, MemoryBase));
+      VirtualMemoryTable[Index].PhysicalBase = MemoryBase;
+      VirtualMemoryTable[Index].VirtualBase  = MemoryBase;
+      VirtualMemoryTable[Index].Length       = MemorySize;
+      VirtualMemoryTable[Index].Attributes   = CacheAttributes;
+
+      Index++;
+  }
+
+  for (Node = 0; Node < MAX_NODES; Node++) {
+    VirtualMemoryTable[Index].PhysicalBase  = FixedPcdGet64(PcdIoBaseAddress) +
+                                                Node * FixedPcdGet64(PcdNodeIoBaseAddress);
+    VirtualMemoryTable[Index].VirtualBase   = FixedPcdGet64(PcdIoBaseAddress) +
+                                                Node * FixedPcdGet64(PcdNodeIoBaseAddress);
+    VirtualMemoryTable[Index].Length        = FixedPcdGet64(PcdIoSize);
+    VirtualMemoryTable[Index].Attributes    = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    DEBUG ((DEBUG_LOAD | DEBUG_INFO,
+            "IO %lx @ %lx\n",
+            VirtualMemoryTable[Index].Length,
+            VirtualMemoryTable[Index].PhysicalBase));
+
+    Index++;
+  }
+
+  // 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/Marvell/Library/SmcLib/SmcLib.c b/Silicon/Marvell/Library/SmcLib/SmcLib.c
new file mode 100644
index 0000000000..0b6970db9f
--- /dev/null
+++ b/Silicon/Marvell/Library/SmcLib/SmcLib.c
@@ -0,0 +1,189 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2023 Marvell
+*
+* Source file for Marvell SMC Interface
+*
+**/
+
+#include <Library/SmcLib.h>     // MV_SMC_ID_NODE_COUNT
+#include <Library/ArmSmcLib.h>  // ArmCallSmc
+#include <Library/PrintLib.h>   // AsciiVSPrint
+#include <IndustryStandard/ArmStdSmc.h> // SMCCC_ARCH_SOC_ID
+#include <Library/DebugLib.h>
+UINTN EFIAPI SmcPciEnumComplete (IN UINTN PemInfo)
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_PCIE_ENUM_DONE;
+  ArmSmcArgs.Arg1 = PemInfo;
+  ArmSmcArgs.Arg2 = 0;
+  ArmSmcArgs.Arg3 = 0;
+  ArmCallSmc(&ArmSmcArgs);
+
+  return ArmSmcArgs.Arg0;
+}
+
+UINTN SmcGetNodeCount (VOID)
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_NODE_COUNT;
+  ArmCallSmc (&ArmSmcArgs);
+
+  return ArmSmcArgs.Arg0;
+}
+
+UINTN SmcGetRamSize ( IN UINTN Node )
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_DRAM_SIZE;
+  ArmSmcArgs.Arg1 = Node;
+  ArmCallSmc (&ArmSmcArgs);
+
+  return ArmSmcArgs.Arg0;
+}
+
+UINTN EFIAPI SmcGetRvuRamSize (
+  IN UINT64 *Address,
+  IN UINT64 *Size )
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_RVU_RSVD_REG_INFO;
+  ArmCallSmc (&ArmSmcArgs);
+
+  *Address = ArmSmcArgs.Arg1;
+  *Size = ArmSmcArgs.Arg2;
+
+  return ArmSmcArgs.Arg0;
+}
+
+UINTN EFIAPI SmcDebugPrint (
+  IN  CONST CHAR8  *FormatString,
+  ...
+  )
+{
+  CHAR8        StringBuffer[256];
+  VA_LIST      Marker;
+  UINTN        NumberOfPrinted,
+               Index;
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  VA_START (Marker, FormatString);
+
+  NumberOfPrinted = AsciiVSPrint (StringBuffer,
+                                  sizeof(StringBuffer),
+                                  FormatString,
+                                  Marker);
+  VA_END (Marker);
+
+  Index = 0;
+
+  while (StringBuffer[Index] != '\0') {
+    ArmSmcArgs.Arg0 = MV_SMC_ID_PUTC;
+    ArmSmcArgs.Arg1 = StringBuffer[Index];
+    ArmCallSmc (&ArmSmcArgs);
+  }
+
+  return NumberOfPrinted;
+}
+
+UINTN EFIAPI SmcShutdownRvu(VOID)
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_DISABLE_RVU_LFS;
+  ArmCallSmc(&ArmSmcArgs);
+
+  return ArmSmcArgs.Arg0;
+}
+
+UINTN EFIAPI SmcBootSuccess(VOID)
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_FSAFE_BOOT_SUCCESS;
+  ArmCallSmc(&ArmSmcArgs);
+
+  return ArmSmcArgs.Arg0;
+}
+
+/**
+  Update firmware image in SPI NOR flash
+
+  @param[in] Buffer - Pointer to buffer that contains firmware image
+  @param[in] Size   - Size of the buffer
+
+  @retval 0         - EFI_SUCCESS
+  @retval -1        - Invalid arguments
+  @retval -2        - SPI_CONFIG_ERR
+  @retval -3        - SPI_MMAP_ERR
+  @retval -4        - SPI_IMG_VALIDATE_ERR
+  @retval -5        - SPI_IMG_UPDATE_ERR
+
+**/
+UINTN EFIAPI SmcSpiSecureUpdate (
+  IN VOID   *Buffer,
+  IN UINTN  Size
+)
+{
+  ARM_SMC_ARGS ArmSmcArgs;
+
+  ArmSmcArgs.Arg0 = MV_SMC_ID_SPI_SECURE_UPDATE;
+  ArmSmcArgs.Arg1 = (UINTN) Buffer;
+  ArmSmcArgs.Arg2 = Size;
+  ArmSmcArgs.Arg3 = 0;
+  ArmCallSmc(&ArmSmcArgs);
+
+  return ArmSmcArgs.Arg0;
+}
+
+// Below function definition based on SmbiosGetSmcArm64SocId() from:
+// boot/uefi/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/SmbiosProcessorArmCommon.c
+
+/** Fetches the JEP106 code and SoC Revision.
+
+    @param Jep106Code  JEP 106 code.
+    @param SocRevision SoC revision.
+
+    @retval EFI_SUCCESS Succeeded.
+    @retval EFI_UNSUPPORTED Failed.
+**/
+EFI_STATUS
+GetSmcArm64SocId (
+  OUT INT32  *Jep106Code,
+  OUT INT32  *SocRevision
+  )
+{
+  INT32       SmcCallStatus;
+  EFI_STATUS  Status;
+  UINTN       SmcParam;
+
+  Status = EFI_SUCCESS;
+
+  SmcParam      = 0; // Get SoC Version
+  SmcCallStatus = ArmCallSmc1 (SMCCC_ARCH_SOC_ID, &SmcParam, NULL, NULL);
+
+  if (SmcCallStatus >= 0) {
+    *Jep106Code = SmcCallStatus;
+  } else {
+    Status = EFI_UNSUPPORTED;
+  }
+
+  SmcParam      = 1;  // Get SoC Revision
+  SmcCallStatus = ArmCallSmc1 (SMCCC_ARCH_SOC_ID, &SmcParam, NULL, NULL);
+
+  if (SmcCallStatus >= 0) {
+    *SocRevision = SmcCallStatus;
+  } else {
+    Status = EFI_UNSUPPORTED;
+  }
+  DEBUG ((DEBUG_INFO, "%a: Status = %r Ver = 0x%x, Rev = 0x%x\n",
+          __func__, Status, *Jep106Code, *SocRevision));
+  return Status;
+}
diff --git a/Silicon/Marvell/Library/SmcLib/SmcLib.inf b/Silicon/Marvell/Library/SmcLib/SmcLib.inf
new file mode 100644
index 0000000000..5053982366
--- /dev/null
+++ b/Silicon/Marvell/Library/SmcLib/SmcLib.inf
@@ -0,0 +1,32 @@
+#/** @file
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+# https://spdx.org/licenses
+#
+# Copyright (C) 2023 Marvell
+#
+# Marvell SMC Interface library
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmcLib
+  FILE_GUID                      = fee427a7-816a-4636-bb81-a640c8288f28
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SmcLib
+
+[Sources]
+  SmcLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+
+  MdePkg/MdePkg.dec
+  Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+
+[LibraryClasses]
+  PrintLib
+  ArmSmcLib
+  DebugLib
diff --git a/Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h b/Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h
new file mode 100644
index 0000000000..b8f5592295
--- /dev/null
+++ b/Silicon/Marvell/MarvellSiliconPkg/Include/Library/SmcLib.h
@@ -0,0 +1,71 @@
+/** @file
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+* https://spdx.org/licenses
+*
+* Copyright (C) 2023 Marvell
+*
+* Header file for for Marvell SMC Interface
+*
+**/
+
+#ifndef __MV_SMCLIB_H__
+#define __MV_SMCLIB_H__
+
+/* SMC function IDs for Marvell Service queries */
+
+#define MV_SMC_ID_CALL_COUNT              0xc200ff00
+#define MV_SMC_ID_UID                     0xc200ff01
+
+#define MV_SMC_ID_VERSION                 0xc200ff03
+
+/* x1 - node number */
+#define MV_SMC_ID_DRAM_SIZE               0xc2000301
+
+#define MV_SMC_ID_NODE_COUNT              0xc2000601
+
+/* x1 - character to print */
+#define MV_SMC_ID_PUTC                    0xc2000a01
+
+#define MV_SMC_ID_DISABLE_RVU_LFS         0xc2000b01
+
+#define MV_SMC_ID_RVU_RSVD_REG_INFO       0xc2000b07
+
+#define MV_SMC_ID_FSAFE_BOOT_SUCCESS      0xc2000b02
+
+#define MV_SMC_ID_SPI_SECURE_UPDATE       0xc2000b05
+
+#define MV_SMC_ID_PCIE_ENUM_DONE          0xc2000c01
+
+UINTN SmcGetNodeCount (VOID);
+
+UINTN SmcGetRamSize (IN UINTN Node);
+
+UINTN EFIAPI SmcGetRvuRamSize (
+  IN UINT64 *Address,
+  IN UINT64 *Size
+);
+
+UINTN EFIAPI SmcDebugPrint (
+  IN  CONST CHAR8  *FormatString,
+  ...
+);
+
+UINTN EFIAPI SmcShutdownRvu (VOID);
+
+UINTN EFIAPI SmcBootSuccess(VOID);
+
+UINTN EFIAPI SmcSpiSecureUpdate (
+  IN VOID   *Buffer,
+  IN UINTN  Size
+);
+
+UINTN EFIAPI SmcPciEnumComplete (IN UINTN PemInfo);
+
+EFI_STATUS
+GetSmcArm64SocId (
+  OUT INT32  *Jep106Code,
+  OUT INT32  *SocRevision
+  );
+
+#endif
diff --git a/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h b/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h
new file mode 100644
index 0000000000..dd9af0bf8f
--- /dev/null
+++ b/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h
@@ -0,0 +1,180 @@
+/** @file
+
+  DISCLAIMER: the FDT_CLIENT_PROTOCOL introduced here is a work in progress,
+  and should not be used outside of the EDK II tree.
+
+  Copyright (C) 2023 Marvell
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FDT_CLIENT_H__
+#define __FDT_CLIENT_H__
+
+#define FDT_CLIENT_PROTOCOL_GUID { \
+  0xE11FACA0, 0x4710, 0x4C8E, {0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C} \
+  }
+
+#define FdtToCpu32(Value) SwapBytes32(Value)
+#define CpuToFdt32(Value) SwapBytes32(Value)
+
+#define FdtToCpu64(Value) SwapBytes64(Value)
+#define CpuToFdt64(Value) SwapBytes64(Value)
+
+//
+// Protocol interface structure
+//
+typedef int FDT_HANDLE;
+#define FDT_START_HANDLE -1
+typedef struct _FDT_CLIENT_PROTOCOL FDT_CLIENT_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NODE_PROPERTY) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  IN  CONST CHAR8             *PropertyName,
+  OUT CONST VOID              **Prop,
+  OUT UINT32                  *PropSize OPTIONAL
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_SET_NODE_PROPERTY) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  IN  CONST CHAR8             *PropertyName,
+  IN  CONST VOID              *Prop,
+  IN  UINT32                  PropSize
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_FIND_COMPATIBLE_NODE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST CHAR8             *CompatibleString,
+  IN  FDT_HANDLE              PrevNode,
+  OUT FDT_HANDLE              *Node
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_FIND_COMPATIBLE_NODE_PROPERTY) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST CHAR8             *CompatibleString,
+  IN  CONST CHAR8             *PropertyName,
+  OUT CONST VOID              **Prop,
+  OUT UINT32                  *PropSize OPTIONAL
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  OUT FDT_HANDLE              *Node
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NODE_DEPTH) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  OUT FDT_HANDLE              *Depth
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_PARENT_NODE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  FDT_HANDLE              Node,
+  OUT FDT_HANDLE              *Parent
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NODE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST CHAR8             *Path,
+  OUT FDT_HANDLE              *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NODE_PATH) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Node,
+  OUT CHAR8                   *Path,
+  IN  INT32                   Size
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        StartNode,
+  IN  CHAR8                   *Property,
+  IN  VOID                    *Value,
+  IN  INT32                   Size,
+  OUT FDT_HANDLE              *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Parent,
+  IN  CHAR8                   *PropertyName,
+  IN  VOID                    *PropertyValue,
+  IN  INT32                   PropertyLength,
+  OUT FDT_HANDLE              *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NODE_BY_PHANDLE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        PHandle,
+  OUT FDT_HANDLE              *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_FIRST_SUBNODE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Parent,
+  OUT FDT_HANDLE              *Node
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *FDT_CLIENT_GET_NEXT_SUBNODE) (
+  IN  FDT_CLIENT_PROTOCOL     *This,
+  IN  CONST FDT_HANDLE        Subnode,
+  OUT FDT_HANDLE              *Next
+  );
+
+struct _FDT_CLIENT_PROTOCOL {
+  FDT_CLIENT_GET_NODE_PROPERTY             GetNodeProperty;
+  FDT_CLIENT_SET_NODE_PROPERTY             SetNodeProperty;
+
+  FDT_CLIENT_FIND_COMPATIBLE_NODE          FindCompatibleNode;
+
+  FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE     GetOrInsertChosenNode;
+
+  FDT_CLIENT_GET_NODE_DEPTH                GetNodeDepth;
+  FDT_CLIENT_GET_PARENT_NODE               GetParentNode;
+  FDT_CLIENT_GET_NODE                      GetNode;
+  FDT_CLIENT_GET_NODE_PATH                 GetNodePath;
+  FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE    GetNodeByPropertyValue;
+  FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE GetSubnodeByPropertyValue;
+  FDT_CLIENT_GET_NODE_BY_PHANDLE           GetNodeByPHandle;
+  FDT_CLIENT_GET_FIRST_SUBNODE             GetFirstSubnode;
+  FDT_CLIENT_GET_NEXT_SUBNODE              GetNextSubnode;
+
+};
+
+extern EFI_GUID gFdtClientProtocolGuid;
+
+#endif
diff --git a/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec b/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
index 1e17152f13..0fb46d1330 100644
--- a/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+++ b/Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
@@ -42,6 +42,8 @@
   # that depend on the lowlevel platform initialization having been completed
   gMarvellPlatformInitCompleteProtocolGuid = { 0x465b8cf7, 0x016f, 0x4ba6, { 0xbe, 0x6b, 0x28, 0x0e, 0x3a, 0x7d, 0x38, 0x6f } }
 
+  gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } }
+
 [PcdsFixedAtBuild.common]
 #Board description
   gMarvellSiliconTokenSpaceGuid.PcdMaxCpCount|0x2|UINT8|0x30000072
@@ -198,6 +200,23 @@
   gMarvellSiliconTokenSpaceGuid.PcdOpTeeRegionBase|0x0|UINT64|0x50000004
   gMarvellSiliconTokenSpaceGuid.PcdOpTeeRegionSize|0x0|UINT32|0x50000005
 
+# FDT
+  # FDT configuration node to be stripped before passing to OS
+  gMarvellSiliconTokenSpaceGuid.PcdFdtConfigRootNode|"/marvell,ebf"|VOID*|0x50000090
+
+  gMarvellSiliconTokenSpaceGuid.PcdNodeDramBase|0x10000000000|UINT64|0x00000004
+  gMarvellSiliconTokenSpaceGuid.PcdIoBaseAddress|0x800000000000|UINT64|0x00000005
+  gMarvellSiliconTokenSpaceGuid.PcdNodeIoBaseAddress|0x100000000000|UINT64|0x00000006
+  gMarvellSiliconTokenSpaceGuid.PcdIoSize|0xF0000000000|UINT64|0x00000007
+
+  gMarvellSiliconTokenSpaceGuid.PcdGtiWatchdogBase64|0x802000000000|UINT64|0x00000008
+
+[PcdsFeatureFlag.common]
+  # Publish FDT to the OS as Configuration Table with gFdtTableGuid
+  gMarvellSiliconTokenSpaceGuid.PcdPublishFdt|FALSE|BOOLEAN|0x50000091
+  # Fixup the FDT or not (taken into consideration only when PcdPublishFdt = TRUE)
+  gMarvellSiliconTokenSpaceGuid.PcdFixupFdt|TRUE|BOOLEAN|0x50000092
+
 [Protocols]
   gMarvellBoardDescProtocolGuid            = { 0xebed8738, 0xd4a6, 0x4001, { 0xa9, 0xc9, 0x52, 0xb0, 0xcb, 0x7d, 0xdb, 0xf9 }}
   gMarvellEepromProtocolGuid               = { 0x71954bda, 0x60d3, 0x4ef8, { 0x8e, 0x3c, 0x0e, 0x33, 0x9f, 0x3b, 0xc2, 0x2b }}
diff --git a/Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc b/Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc
new file mode 100644
index 0000000000..1c69ca8696
--- /dev/null
+++ b/Silicon/Marvell/OdysseyPkg/OdysseyPkg.dsc.inc
@@ -0,0 +1,394 @@
+#/** @file
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#  https://spdx.org/licenses
+#
+#  Copyright (C) 2023 Marvell
+#
+#  DSC include file for OdysseyPkg.
+#
+#  This file can be included to platform DSC file
+#  by using "!include OdysseyPkg.dsc.inc" // path relative to platform DSC file.
+#
+#**/
+
+[Defines]
+  SECURE_BOOT_ENABLE = FALSE
+  MIN_IMAGE = FALSE
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000
+  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
+
+[LibraryClasses.common]
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
+
+  #
+  # Assume everything is fixed at build
+  #
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+  NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
+#!if $(MIN_IMAGE) == FALSE
+  # Networking Requirements
+  DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf
+  UdpIoLib|NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  IpIoLib|NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+#!endif
+
+  # ARM Architectural Libraries
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
+
+  # Boot manager
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+
+  # Silicon Specific Libraries
+  PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+  # ARM PL011 UART Library
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+  PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
+
+  #
+  # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
+  # in the debugger will show load and unload commands for symbols. You can cut and paste this
+  # into the command window to load symbols. We should be able to use a script to do this, but
+  # the version of RVD I have does not support scripts accessing system memory.
+  #
+  #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+  #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
+
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+
+  # RunAxf support via Dynamic Shell Command protocol
+  # It uses the Shell libraries.
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+  #
+  # Secure Boot dependencies
+  #
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+
+  # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
+  PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  # Platform Support Libraries
+  SmcLib|Silicon/Marvell/Library/SmcLib/SmcLib.inf
+
+[LibraryClasses.common.SEC]
+
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+
+  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.PEIM]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+
+  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.SEC, LibraryClasses.common.PEIM]
+  MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  # ARM PL011 UART Runtime Library
+  #SerialPortLib|Silicon/Marvell/Library/PL011SerialPortRuntimeLib/PL011SerialPortRuntimeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+!endif
+
+[LibraryClasses.AARCH64.DXE_RUNTIME_DRIVER]
+  #
+  # PSCI support in EL3 may not be available if we are not running under a PSCI
+  # compliant secure firmware, but since the default VExpress EfiResetSystemLib
+  # cannot be supported at runtime (due to the fact that the syscfg MMIO registers
+  # cannot be runtime remapped), it is our best bet to get ResetSystem functionality
+  # on these platforms.
+  #
+  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+  #
+  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+  # This library provides the instrinsic functions generate by a given compiler.
+  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+  #
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+  # Add support for GCC stack protector
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+
+[BuildOptions]
+  RVCT:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
+
+  GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+
+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+!ifdef $(FIRMWARE_VER)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"MARVELL UEFI 5.0.0"
+!endif
+
+!ifdef $(RELEASE_DATE)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString|L"$(RELEASE_DATE)"
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString|L"2022"
+!endif
+
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1  #  BIT0 - Enable Performance Measurement.
+
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free's
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free's
+  #  DEBUG_INFO      0x00000040  // Verbose
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNI Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // UNDI Driver
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80304FCF
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  # RunAxf support via Dynamic Shell Command protocol
+  # We want to use the Shell Libraries but do not want it to initialise
+  # automatically. We initialise the libraries when the command is called by the
+  # Shell.
+  gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  # Define PcdBootManagerMenuFile as FILE_GUID of bootloader/uefi/MdeModulePkg/Application/UiApp/UiApp.inf
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  # Max capsule size
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x1400000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule|0x1400000
+
+  # Use MPIDR Affinity Level 2 to identify the PrimaryCore
+  # Affinity Level 2: number of clusters up to 64 (CN10K)/ 80 (Odyssey)/ 16 (Iliad)
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask|0xFF0000
+
+[PcdsDynamicHii.common.DEFAULT]
+!if $(MIN_IMAGE) == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+!endif
+
+[Components.common]
+
+  # FV Filesystem
+  MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+
+  # SectionExtraction
+  MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf {
+    <LibraryClasses>
+      ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  }
+
+  #
+  # FDT support
+  #
+  Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
+  Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
+
+  # No EMMC/SD Interface
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+  }
+
+  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
+  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+  }
diff --git a/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
new file mode 100644
index 0000000000..481d794154
--- /dev/null
+++ b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,136 @@
+//
+//  Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLibV8.h>
+GCC_ASM_IMPORT(mDeviceTreeBaseAddress)  // --- MRVL Override: defined in PrePi.c
+GCC_ASM_IMPORT(mSystemMemoryEnd)        // --- MRVL Override
+ASM_FUNC(_ModuleEntryPoint)
+
+  // --- MRVL Override start
+  // Save the boot parameter to a global variable
+  adr   x10, mDeviceTreeBaseAddress
+  str   x1, [x10]
+  // --- MRVL Override end
+
+  // Do early platform specific actions
+  bl    ASM_PFX(ArmPlatformPeiBootAction)
+
+  // Get ID of this CPU in multi-core system
+  bl    ASM_PFX(ArmReadMpidr)
+  // Keep a copy of the MpId register value
+  mov   x10, x0
+
+_SetSVCMode:
+// Check if we can install the stack at the top of the System Memory or if we need
+// to install the stacks at the bottom of the Firmware Device (case the FD is located
+// at the top of the DRAM)
+_SystemMemoryEndInit:
+  ldr   x1, mSystemMemoryEnd
+
+  // --- MRVL Override start
+  // mSystemMemoryEnd shall be set by SMC call within ArmPlatformPeiBootAction
+  cmp   x1, #0xffffffffffffffff
+  bne   _SetupStackPosition
+  // if mSystemMemoryEnd wasn't gethered from SMC call, get it from PCDs
+  MOV64 (x1, FixedPcdGet64(PcdSystemMemoryBase) + FixedPcdGet64(PcdSystemMemorySize) - 1)
+
+  // Update the global variable
+  adr   x2, mSystemMemoryEnd
+  str   x1, [x2]
+  // --- MRVL Override end
+
+_SetupStackPosition:
+  // x1 = SystemMemoryTop
+
+  // Calculate Top of the Firmware Device
+  MOV64 (x2, FixedPcdGet64(PcdFdBaseAddress))
+  MOV32 (x3, FixedPcdGet32(PcdFdSize) - 1)
+  sub   x3, x3, #1
+  add   x3, x3, x2      // x3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+  // UEFI Memory Size (stacks are allocated in this region)
+  MOV32 (x4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
+
+  //
+  // Reserve the memory for the UEFI region (contain stacks on its top)
+  //
+
+  // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
+  subs  x0, x1, x3   // x0 = SystemMemoryTop - FdTop
+  b.mi  _SetupStack  // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+  cmp   x0, x4
+  b.ge  _SetupStack
+
+  // Case the top of stacks is the FdBaseAddress
+  mov   x1, x2
+
+_SetupStack:
+  // x1 contains the top of the stack (and the UEFI Memory)
+
+  // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
+  // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
+  // top of the memory space)
+  adds  x11, x1, #1
+  b.cs  _SetupOverflowStack
+
+_SetupAlignedStack:
+  mov   x1, x11
+  b     _GetBaseUefiMemory
+
+_SetupOverflowStack:
+  // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+  // aligned (4KB)
+  and   x1, x1, ~EFI_PAGE_MASK
+
+_GetBaseUefiMemory:
+  // Calculate the Base of the UEFI Memory
+  sub   x11, x1, x4
+
+_GetStackBase:
+  // r1 = The top of the Mpcore Stacks
+  // Stack for the primary core = PrimaryCoreStack
+  MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+  sub   x12, x1, x2
+
+  // Stack for the secondary core = Number of Cores - 1
+  MOV32 (x1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+  sub   x12, x12, x1
+
+  // x12 = The base of the MpCore Stacks (primary stack & secondary stacks)
+  mov   x0, x12
+  mov   x1, x10
+  //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+  MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+  MOV32 (x3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+  bl    ASM_PFX(ArmPlatformStackSet)
+
+  // Is it the Primary Core ?
+  mov   x0, x10
+  bl    ASM_PFX(ArmPlatformIsPrimaryCore)
+  cmp   x0, #1
+  bne   _PrepareArguments
+
+_PrepareArguments:
+  mov   x0, x10
+  mov   x1, x11
+  mov   x2, x12
+
+  // Move sec startup address into a data register
+  // Ensure we're jumping to FV version of the code (not boot remapped alias)
+  ldr   x4, =ASM_PFX(CEntryPoint)
+
+  // Set the frame pointer to NULL so any backtraces terminate here
+  mov   x29, xzr
+
+  // Jump to PrePiCore C code
+  //    x0 = MpId
+  //    x1 = UefiMemoryBase
+  //    x2 = StacksBase
+  blr   x4
+
+_NeverReturn:
+  b _NeverReturn
diff --git a/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf
new file mode 100644
index 0000000000..49d9e406d7
--- /dev/null
+++ b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -0,0 +1,110 @@
+#/** @file
+#
+#  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+#  Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmPlatformPrePiMPCore
+  FILE_GUID                      = d959e387-7b91-452c-90e0-a1dbac90ddb8
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  DEFINE ORG_SOURCES_PATH        = ArmPlatformPkg/PrePi # --- MRVL Override
+
+[Sources]
+  $(ORG_SOURCES_PATH)/PrePi.h       # --- MRVL Override
+  PrePi.c
+  $(ORG_SOURCES_PATH)/MainMPCore.c  # --- MRVL Override
+
+[Sources.ARM]
+  $(ORG_SOURCES_PATH)/Arm/ArchPrePi.c                   # --- MRVL Override
+  $(ORG_SOURCES_PATH)/Arm/ModuleEntryPoint.S   | GCC    # --- MRVL Override
+  $(ORG_SOURCES_PATH)/Arm/ModuleEntryPoint.asm | RVCT   # --- MRVL Override
+
+[Sources.AArch64]
+  $(ORG_SOURCES_PATH)/AArch64/ArchPrePi.c               # --- MRVL Override
+  AArch64/ModuleEntryPoint.S
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  CacheMaintenanceLib
+  DebugLib
+  DebugAgentLib
+  ArmLib
+  ArmGicLib
+  IoLib
+  TimerLib
+  SerialPortLib
+  ExtractGuidedSectionLib
+  LzmaDecompressLib
+  DebugAgentLib
+  PrePiLib
+  ArmPlatformLib
+  ArmPlatformStackLib
+  MemoryAllocationLib
+  HobLib
+  PrePiHobListPointerLib
+  PlatformPeiLib
+  MemoryInitPeiLib
+  FdtLib  # --- MRVL Override
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
+
+[Guids]
+  gArmMpCoreInfoGuid
+  gEfiFirmwarePerformanceGuid
+  gFdtHobGuid  # --- MRVL Override
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdVFPEnabled
+
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+  gArmTokenSpaceGuid.PcdFvSize
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+  gArmTokenSpaceGuid.PcdGicDistributorBase
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+  gArmTokenSpaceGuid.PcdGicSgiIntId
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
diff --git a/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c
new file mode 100644
index 0000000000..5168881b18
--- /dev/null
+++ b/Silicon/Marvell/Override/ArmPlatformPkg/PrePi/PrePi.c
@@ -0,0 +1,238 @@
+/** @file
+
+  Copyright (c) 2011-2017, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/SecPerformance.h>
+
+#include "PrePi.h"
+#include <libfdt.h> // fdt_totalsize // --- MRVL Override
+
+#define IS_XIP()  (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\
+                  ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase)))
+
+UINT64  mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) +
+                           FixedPcdGet64 (PcdSystemMemorySize) - 1;
+
+UINT64 mDeviceTreeBaseAddress = 0; // --- MRVL Override
+int fdt_check_header(const void *fdt);
+
+EFI_STATUS
+GetPlatformPpi (
+  IN  EFI_GUID  *PpiGuid,
+  OUT VOID      **Ppi
+  )
+{
+  UINTN                   PpiListSize;
+  UINTN                   PpiListCount;
+  EFI_PEI_PPI_DESCRIPTOR  *PpiList;
+  UINTN                   Index;
+
+  PpiListSize = 0;
+  ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
+  PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR);
+  for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
+    if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
+      *Ppi = PpiList->Ppi;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+VOID
+PrePiMain (
+  IN  UINTN   UefiMemoryBase,
+  IN  UINTN   StacksBase,
+  IN  UINT64  StartTimeStamp
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *HobList;
+  ARM_MP_CORE_INFO_PPI        *ArmMpCoreInfoPpi;
+  UINTN                       ArmCoreCount;
+  ARM_CORE_INFO               *ArmCoreInfoTable;
+  EFI_STATUS                  Status;
+  CHAR8                       Buffer[500];  // --- MRVL Override
+  UINTN                       CharCount;
+  UINTN                       StacksSize;
+  FIRMWARE_SEC_PERFORMANCE    Performance;
+
+  // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
+  ASSERT (
+    IS_XIP () ||
+    ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
+     ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd))
+    );
+
+  // Initialize the architecture specific bits
+  ArchInitialize ();
+
+  // Initialize the Serial Port
+  SerialPortInitialize ();
+  CharCount = AsciiSPrint (
+                Buffer,
+                sizeof (Buffer),
+                "UEFI firmware (version %s built at %a on %a)\n\r",
+                (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
+                __TIME__,
+                __DATE__
+                );
+  SerialPortWrite ((UINT8 *)Buffer, CharCount);
+
+  // Initialize the Debug Agent for Source Level Debugging
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+  SaveAndSetDebugTimerInterrupt (TRUE);
+
+  // Declare the PI/UEFI memory region
+  HobList = HobConstructor (
+              (VOID *)UefiMemoryBase,
+              FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
+              (VOID *)UefiMemoryBase,
+              (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks
+              );
+  PrePeiSetHobList (HobList);
+
+  // --- MRVL Override start
+  // Build the FDT HOB
+  ASSERT(fdt_check_header ((VOID *)mDeviceTreeBaseAddress) == 0);
+  DEBUG((DEBUG_INFO, "FDT address: %lx, size: %d\n",
+          mDeviceTreeBaseAddress,
+          fdt_totalsize((VOID *)mDeviceTreeBaseAddress)));
+
+  BuildGuidDataHob (&gFdtHobGuid, &mDeviceTreeBaseAddress, sizeof(mDeviceTreeBaseAddress));
+  // --- MRVL Override end
+
+  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+  ASSERT_EFI_ERROR (Status);
+
+  // Create the Stacks HOB (reserve the memory for all stacks)
+  if (ArmIsMpCore ()) {
+    StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
+                 ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
+  } else {
+    StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+  }
+
+  BuildStackHob (StacksBase, StacksSize);
+
+  // TODO: Call CpuPei as a library
+  BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
+
+  if (ArmIsMpCore ()) {
+    // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
+    Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi);
+
+    // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
+    ASSERT_EFI_ERROR (Status);
+
+    // Build the MP Core Info Table
+    ArmCoreCount = 0;
+    Status       = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
+    if (!EFI_ERROR (Status) && (ArmCoreCount > 0)) {
+      // Build MPCore Info HOB
+      BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
+    }
+  }
+
+  // Store timer value logged at the beginning of firmware image execution
+  Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp);
+
+  // Build SEC Performance Data Hob
+  BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance));
+
+  // Set the Boot Mode
+  SetBootMode (ArmPlatformGetBootMode ());
+
+  // Initialize Platform HOBs (CpuHob and FvHob)
+  Status = PlatformPeim ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Now, the HOB List has been initialized, we can register performance information
+  PERF_START (NULL, "PEI", NULL, StartTimeStamp);
+
+  // SEC phase needs to run library constructors by hand.
+  ProcessLibraryConstructorList ();
+
+  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
+  Status = DecompressFirstFv ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Load the DXE Core and transfer control to it
+  Status = LoadDxeCoreFromFv (NULL, 0);
+  ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+CEntryPoint (
+  IN  UINTN  MpId,
+  IN  UINTN  UefiMemoryBase,
+  IN  UINTN  StacksBase
+  )
+{
+  UINT64  StartTimeStamp;
+
+  // Initialize the platform specific controllers
+  ArmPlatformInitialize (MpId);
+
+  if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) {
+    // Initialize the Timer Library to setup the Timer HW controller
+    TimerConstructor ();
+    // We cannot call yet the PerformanceLib because the HOB List has not been initialized
+    StartTimeStamp = GetPerformanceCounter ();
+  } else {
+    StartTimeStamp = 0;
+  }
+
+  // Data Cache enabled on Primary core when MMU is enabled.
+  ArmDisableDataCache ();
+  // Invalidate instruction cache
+  ArmInvalidateInstructionCache ();
+  // Enable Instruction Caches on all cores.
+  ArmEnableInstructionCache ();
+
+  // Define the Global Variable region when we are not running in XIP
+  if (!IS_XIP ()) {
+    if (ArmPlatformIsPrimaryCore (MpId)) {
+      if (ArmIsMpCore ()) {
+        // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
+        ArmCallSEV ();
+      }
+    } else {
+      // Wait the Primary core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT)
+      ArmCallWFE ();
+    }
+  }
+
+  // If not primary Jump to Secondary Main
+  if (ArmPlatformIsPrimaryCore (MpId)) {
+    InvalidateDataCacheRange (
+      (VOID *)UefiMemoryBase,
+      FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
+      );
+
+    // Goto primary Main.
+    PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+  } else {
+    SecondaryMain (MpId);
+  }
+
+  // DXE Core should always load and never return
+  ASSERT (FALSE);
+}

base-commit: 787154b500434dfdcd942015fe0a7184c0d2daa9
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111908): https://edk2.groups.io/g/devel/message/111908
Mute This Topic: https://groups.io/mt/102895289/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-12-08 16:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-30 15:14 [edk2-devel] [edk2-platforms PATCH 1/1] Silicon/Marvell/OdysseyPkg: New Marvell Odyssey processor Narinder Dhillon
2023-12-08 16:37 ` Marcin Wojtas via groups.io

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox