public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms
@ 2017-11-16 17:58 Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 01/13] Platform: remove bogus ArmPlatformSecExtraActionLib references Ard Biesheuvel
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

This is mostly a preparatory series that will allow us to get rid of a lot
of code that is specific to only a single ARM development platform out of
the main EDK2 tree.

First of all, it removes a couple of false dependencies of various platforms
on libraries that are no longer used, or not actually used by the platform
in question. Patches #5, #6 and #11 move the bulk of the support for ARM
development platforms into edk2-platforms.

Ard Biesheuvel (13):
  Platform: remove bogus ArmPlatformSecExtraActionLib references
  Platform: remove bogus ArmTrustedMonitorLib references
  Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference
  Platform/Hisilicon: remove bogus VExpress dependencies
  Platform/ARM/Juno: import ArmJunoPkg from EDK2
  Platform/ARM/VExpress: import VExpressPkg from EDK2
  Platform/ARM: remove outdated SP804 TimerLib reference
  Platform/Hisilicon: remove SP804 PCD definitions
  Platform: remove references to EBL libraries
  Platform: remove stale PL35xSmcLib references
  Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2
  Platform: remove stale EBL related PCD setting
  Platform: switch to new PL011UartLib

 Platform/AMD/OverdriveBoard/OverdriveBoard.dsc                                                     |    6 +-
 Platform/ARM/ARM.dec                                                                               |   25 +
 Platform/ARM/Drivers/BootMonFs/BootMonFs.dec                                                       |   26 +
 Platform/ARM/Drivers/BootMonFs/BootMonFs.inf                                                       |   63 ++
 Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h                                                      |  388 +++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c                                                      |  766 ++++++++++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c                                               |  529 ++++++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h                                                       |   57 ++
 Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c                                                   |  222 ++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h                                                 |  101 ++
 Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c                                                |  795 +++++++++++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c                                                |  259 +++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c                                              |   37 +
 Platform/ARM/Include/Guid/BootMonFsFileInfo.h                                                      |   47 +
 Platform/ARM/Include/Library/ArmShellCmdLib.h                                                      |   57 ++
 Platform/ARM/JunoPkg/AcpiTables/AcpiTables.inf                                                     |    3 +-
 Platform/ARM/JunoPkg/ArmJuno.dec                                                                   |   48 +
 Platform/ARM/JunoPkg/ArmJuno.dsc                                                                   |   12 +-
 Platform/ARM/JunoPkg/ArmJuno.fdf                                                                   |    4 +-
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/AcpiTables.c                                               |   78 ++
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c                                               |  550 ++++++++++
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf                                             |   89 ++
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h                                       |   54 +
 Platform/ARM/JunoPkg/Include/ArmPlatform.h                                                         |  180 ++++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/AArch64/ArmJunoHelper.S                                    |   58 ++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/Arm/ArmJunoHelper.S                                        |   91 ++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJuno.c                                                  |  193 ++++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf                                             |   80 ++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoMem.c                                               |  173 ++++
 Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf                         |    2 +-
 Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c                                        |   68 ++
 Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf                                   |   33 +
 Platform/ARM/JunoPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf                                       |    2 +-
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c                                         |   95 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h                                         |   83 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf                                       |   54 +
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni                                       |   68 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c                                           |  154 +++
 Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h                                           |   66 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c                                                 |  340 +++++++
 Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h                                                 |   64 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c                                                    |  395 ++++++++
 Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h                                                     |  258 +++++
 Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h                                                     |  260 +++++
 Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h                                                | 1059 ++++++++++++++++++++
 Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf                                                 |    3 +-
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc                                                  |   37 +-
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf                                                  |   12 +-
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc                                               |   22 +-
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf                                               |    2 +-
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc                                                       |   41 +-
 Platform/ARM/VExpressPkg/ArmVExpressPkg.dec                                                        |   53 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c                                        |   90 ++
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf                                      |   39 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c                                         |   38 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf                                       |   38 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c                      |  519 ++++++++++
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf                 |   51 +
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c                                      |  133 +++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf                   |   63 ++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c                       |  882 ++++++++++++++++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c                       |  393 ++++++++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h                       |  128 +++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c                                   |  126 +++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf                |   59 ++
 Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h                                                   |   89 ++
 Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h                                                |  149 +++
 Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h                                 |   63 ++
 Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h                                          |  221 ++++
 Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h                                   |  154 +++
 Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h                                       |   79 ++
 Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h                                             |  140 +++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf                         |   54 +
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c                                 |  195 ++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S                           |   81 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm                         |   96 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c                              |  182 ++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S                           |   61 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S                               |   97 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm                             |  118 +++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf                             |   63 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf                          |   59 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c                                         |  209 ++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c                                      |  161 +++
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c                    |  273 +++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf               |   35 +
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c   |  283 ++++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf |   37 +
 Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c                            |  285 ++++++
 Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf                       |   45 +
 Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c                      |   84 ++
 Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf                 |   33 +
 Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c                      |  370 +++++++
 Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf                 |   44 +
 Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c                                   |  111 ++
 Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf                                 |   36 +
 Platform/Hisilicon/D02/Pv660D02.dsc                                                                |   13 -
 Platform/Hisilicon/D03/D03.dsc                                                                     |   15 -
 Platform/Hisilicon/D05/D05.dsc                                                                     |    6 -
 Platform/Hisilicon/HiKey/HiKey.dsc                                                                 |    4 +-
 Platform/LeMaker/CelloBoard/CelloBoard.dsc                                                         |    6 +-
 Platform/Marvell/Armada/Armada.dsc.inc                                                             |    7 -
 Platform/Socionext/DeveloperBox/DeveloperBox.dsc                                                   |    2 +-
 Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc                                       |    2 +-
 Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc                                        |    6 +-
 Silicon/Hisilicon/Hisilicon.dsc.inc                                                                |   21 +-
 106 files changed, 14547 insertions(+), 163 deletions(-)
 create mode 100644 Platform/ARM/ARM.dec
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFs.dec
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c
 create mode 100644 Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c
 create mode 100644 Platform/ARM/Include/Guid/BootMonFsFileInfo.h
 create mode 100644 Platform/ARM/Include/Library/ArmShellCmdLib.h
 create mode 100644 Platform/ARM/JunoPkg/ArmJuno.dec
 create mode 100644 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/AcpiTables.c
 create mode 100644 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
 create mode 100644 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
 create mode 100644 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h
 create mode 100644 Platform/ARM/JunoPkg/Include/ArmPlatform.h
 create mode 100644 Platform/ARM/JunoPkg/Library/ArmJunoLib/AArch64/ArmJunoHelper.S
 create mode 100644 Platform/ARM/JunoPkg/Library/ArmJunoLib/Arm/ArmJunoHelper.S
 create mode 100644 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJuno.c
 create mode 100644 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
 create mode 100644 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoMem.c
 create mode 100644 Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c
 create mode 100644 Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h
 create mode 100644 Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h
 create mode 100644 Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c
 create mode 100644 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
 create mode 100644 Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h
 create mode 100644 Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h
 create mode 100644 Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h
 create mode 100644 Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h
 create mode 100644 Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h
 create mode 100644 Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h
 create mode 100644 Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
 create mode 100644 Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c
 create mode 100644 Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf

-- 
2.11.0



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

* [PATCH edk2-platforms v2 01/13] Platform: remove bogus ArmPlatformSecExtraActionLib references
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 02/13] Platform: remove bogus ArmTrustedMonitorLib references Ard Biesheuvel
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Remove copy-pasted ArmPlatformSecExtraActionLib library class resolutions
that none of the platforms actually need.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/AMD/OverdriveBoard/OverdriveBoard.dsc              | 2 --
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc                | 2 --
 Platform/LeMaker/CelloBoard/CelloBoard.dsc                  | 2 --
 Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc | 2 --
 Silicon/Hisilicon/Hisilicon.dsc.inc                         | 2 --
 5 files changed, 10 deletions(-)

diff --git a/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc b/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
index 8620f6be3514..ec350c999f19 100644
--- a/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
+++ b/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
@@ -172,8 +172,6 @@ [LibraryClasses.common.SEC]
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   ArmPlatformLib|Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf
 
-  ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
-
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 1605eedbdd8c..7b405a949ebd 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -156,8 +156,6 @@ [LibraryClasses.common]
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
 
 [LibraryClasses.common.SEC]
-  ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
-
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
diff --git a/Platform/LeMaker/CelloBoard/CelloBoard.dsc b/Platform/LeMaker/CelloBoard/CelloBoard.dsc
index e03c7c4c3526..7c4adb3a53bf 100644
--- a/Platform/LeMaker/CelloBoard/CelloBoard.dsc
+++ b/Platform/LeMaker/CelloBoard/CelloBoard.dsc
@@ -151,8 +151,6 @@ [LibraryClasses.common.SEC]
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   ArmPlatformLib|Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf
 
-  ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
-
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
diff --git a/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc b/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
index 29ce8b3bd18e..73c0c7531f26 100644
--- a/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
+++ b/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
@@ -157,8 +157,6 @@ [LibraryClasses.common.SEC]
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   ArmPlatformLib|Silicon/AMD/Styx/Library/AmdStyxLib/AmdStyxLibSec.inf
 
-  ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
-
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index d77f0e35431e..c1c947f38cba 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -124,8 +124,6 @@ [LibraryClasses.common]
   NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
 
 [LibraryClasses.common.SEC]
-  ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
-
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
   # Trustzone Support
-- 
2.11.0



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

* [PATCH edk2-platforms v2 02/13] Platform: remove bogus ArmTrustedMonitorLib references
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 01/13] Platform: remove bogus ArmPlatformSecExtraActionLib references Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 03/13] Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference Ard Biesheuvel
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Remove copy-pasted ArmTrustedMonitorLib library class resolutions
that none of the platforms actually need.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/AMD/OverdriveBoard/OverdriveBoard.dsc              | 2 --
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc                | 3 ---
 Platform/LeMaker/CelloBoard/CelloBoard.dsc                  | 2 --
 Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc | 2 --
 Silicon/Hisilicon/Hisilicon.dsc.inc                         | 3 ---
 5 files changed, 12 deletions(-)

diff --git a/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc b/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
index ec350c999f19..7258daa76094 100644
--- a/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
+++ b/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
@@ -175,8 +175,6 @@ [LibraryClasses.common.SEC]
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
-  # Trustzone Support
-  ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
   ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
 
 [LibraryClasses.common.PEIM, LibraryClasses.common.SEC]
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 7b405a949ebd..3db269086d5b 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -169,9 +169,6 @@ [LibraryClasses.common.SEC]
   PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
 !endif
 
-  # Trustzone Support
-  ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
-
   ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
 
 [LibraryClasses.common.PEI_CORE]
diff --git a/Platform/LeMaker/CelloBoard/CelloBoard.dsc b/Platform/LeMaker/CelloBoard/CelloBoard.dsc
index 7c4adb3a53bf..30b080495639 100644
--- a/Platform/LeMaker/CelloBoard/CelloBoard.dsc
+++ b/Platform/LeMaker/CelloBoard/CelloBoard.dsc
@@ -154,8 +154,6 @@ [LibraryClasses.common.SEC]
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
-  # Trustzone Support
-  ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
   ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
 
 [LibraryClasses.common.PEIM, LibraryClasses.common.SEC]
diff --git a/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc b/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
index 73c0c7531f26..5cbf3628fb89 100644
--- a/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
+++ b/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
@@ -160,8 +160,6 @@ [LibraryClasses.common.SEC]
   DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
-  # Trustzone Support
-  ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
   ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
 
 [LibraryClasses.common.PEIM, LibraryClasses.common.SEC]
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index c1c947f38cba..fbecb6497469 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -126,9 +126,6 @@ [LibraryClasses.common]
 [LibraryClasses.common.SEC]
   DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
 
-  # Trustzone Support
-  ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
-
   ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
-- 
2.11.0



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

* [PATCH edk2-platforms v2 03/13] Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 01/13] Platform: remove bogus ArmPlatformSecExtraActionLib references Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 02/13] Platform: remove bogus ArmTrustedMonitorLib references Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 04/13] Platform/Hisilicon: remove bogus VExpress dependencies Ard Biesheuvel
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

No FVP driver uses this library so remove the resolution.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
index 51f0529db251..fc628ad08c9e 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
@@ -62,7 +62,6 @@ [LibraryClasses.common]
   DtPlatformDtbLoaderLib|Platform/ARM/VExpressPkg/Library/ArmVExpressDtPlatformDtbLoaderLib/ArmVExpressDtPlatformDtbLoaderLib.inf
 
 [LibraryClasses.common.SEC]
-  ArmPlatformSecLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf
   ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
 
 [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
-- 
2.11.0



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

* [PATCH edk2-platforms v2 04/13] Platform/Hisilicon: remove bogus VExpress dependencies
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 03/13] Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 05/13] Platform/ARM/Juno: import ArmJunoPkg from EDK2 Ard Biesheuvel
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Remove false copy-pasted dependencies on various VExpress support
libraries.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/Hisilicon/D02/Pv660D02.dsc | 3 ---
 Platform/Hisilicon/D03/D03.dsc      | 5 -----
 Platform/Hisilicon/D05/D05.dsc      | 4 ----
 Platform/Hisilicon/HiKey/HiKey.dsc  | 1 -
 Silicon/Hisilicon/Hisilicon.dsc.inc | 5 -----
 5 files changed, 18 deletions(-)

diff --git a/Platform/Hisilicon/D02/Pv660D02.dsc b/Platform/Hisilicon/D02/Pv660D02.dsc
index 1fd2b98f1552..ba3047882611 100644
--- a/Platform/Hisilicon/D02/Pv660D02.dsc
+++ b/Platform/Hisilicon/D02/Pv660D02.dsc
@@ -36,9 +36,6 @@ [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
   ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLib.inf
 
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
   I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
 
diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc
index f2a120e31b16..491862a3b27e 100644
--- a/Platform/Hisilicon/D03/D03.dsc
+++ b/Platform/Hisilicon/D03/D03.dsc
@@ -36,11 +36,6 @@ [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
   ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLib.inf
 
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
-
-
   I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
 
diff --git a/Platform/Hisilicon/D05/D05.dsc b/Platform/Hisilicon/D05/D05.dsc
index 64101a7d0160..de2d3579a494 100644
--- a/Platform/Hisilicon/D05/D05.dsc
+++ b/Platform/Hisilicon/D05/D05.dsc
@@ -38,10 +38,6 @@ [Defines]
 [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
   ArmPlatformLib|Silicon/Hisilicon/Library/ArmPlatformLibHisilicon/ArmPlatformLib.inf
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
-
 
   I2CLib|Silicon/Hisilicon/Library/I2CLib/I2CLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
diff --git a/Platform/Hisilicon/HiKey/HiKey.dsc b/Platform/Hisilicon/HiKey/HiKey.dsc
index 2e3b1c8799cc..f0380ee1f929 100644
--- a/Platform/Hisilicon/HiKey/HiKey.dsc
+++ b/Platform/Hisilicon/HiKey/HiKey.dsc
@@ -45,7 +45,6 @@ [LibraryClasses.common]
   ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
   ArmPlatformLib|Platform/Hisilicon/HiKey/Library/HiKeyLib/HiKeyLib.inf
   ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
-  ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
 
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index fbecb6497469..f24f6dabd12c 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -62,12 +62,7 @@ [LibraryClasses.common]
   ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
   ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
 
-  # Versatile Express Specific Libraries
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
   ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
-  # ARM PL111 Lcd Driver
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
 
   # ARM PL354 SMC Driver
   PL35xSmcLib|ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf
-- 
2.11.0



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

* [PATCH edk2-platforms v2 05/13] Platform/ARM/Juno: import ArmJunoPkg from EDK2
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 04/13] Platform/Hisilicon: remove bogus VExpress dependencies Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 06/13] Platform/ARM/VExpress: import VExpressPkg " Ard Biesheuvel
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Move ArmJunoPkg into edk2-platforms, so it can be removed from the main
EDK2 tree.

This allows use to remove the dodgy -I arguments to GCC to build shared
modules with a different copy of ArmPlatform.h, which was making it very
difficult to properly split the various modules into their own packages.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/JunoPkg/AcpiTables/AcpiTables.inf                             |   3 +-
 Platform/ARM/JunoPkg/ArmJuno.dec                                           |  48 ++
 Platform/ARM/JunoPkg/ArmJuno.dsc                                           |   8 +-
 Platform/ARM/JunoPkg/ArmJuno.fdf                                           |   2 +-
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/AcpiTables.c                       |  78 +++
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c                       | 550 ++++++++++++++++++++
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf                     |  88 ++++
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h               |  54 ++
 Platform/ARM/JunoPkg/Include/ArmPlatform.h                                 | 180 +++++++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/AArch64/ArmJunoHelper.S            |  58 +++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/Arm/ArmJunoHelper.S                |  91 ++++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJuno.c                          | 193 +++++++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf                     |  80 +++
 Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoMem.c                       | 173 ++++++
 Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf |   2 +-
 Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c                |  68 +++
 Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf           |  33 ++
 Platform/ARM/JunoPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf               |   2 +-
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc                          |  12 +
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc                       |   3 +
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc                               |  10 -
 21 files changed, 1716 insertions(+), 20 deletions(-)

diff --git a/Platform/ARM/JunoPkg/AcpiTables/AcpiTables.inf b/Platform/ARM/JunoPkg/AcpiTables/AcpiTables.inf
index 741ea191be36..539974ff2416 100644
--- a/Platform/ARM/JunoPkg/AcpiTables/AcpiTables.inf
+++ b/Platform/ARM/JunoPkg/AcpiTables/AcpiTables.inf
@@ -33,11 +33,10 @@ [Sources]
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
-  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
-  ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
   EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  Platform/ARM/JunoPkg/ArmJuno.dec
 
 [FixedPcd]
   gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/JunoPkg/ArmJuno.dec b/Platform/ARM/JunoPkg/ArmJuno.dec
new file mode 100644
index 000000000000..60cef6d23a2d
--- /dev/null
+++ b/Platform/ARM/JunoPkg/ArmJuno.dec
@@ -0,0 +1,48 @@
+#
+#  Copyright (c) 2013-2015, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001A
+  PACKAGE_NAME                   = ArmJunoPkg
+  PACKAGE_GUID                   = a1147a20-3144-4f8d-8295-b48311c8e4a4
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+
+[Guids.common]
+  gArmJunoTokenSpaceGuid    =  { 0xa1147a20, 0x3144, 0x4f8d, { 0x82, 0x95, 0xb4, 0x83, 0x11, 0xc8, 0xe4, 0xa4 } }
+
+[PcdsFeatureFlag.common]
+  gArmJunoTokenSpaceGuid.PcdPciMaxPayloadFixup|FALSE|BOOLEAN|0x00000013
+
+[PcdsFixedAtBuild.common]
+  gArmJunoTokenSpaceGuid.PcdPcieControlBaseAddress|0x7FF20000|UINT64|0x0000000B
+  gArmJunoTokenSpaceGuid.PcdPcieRootPortBaseAddress|0x7FF30000|UINT64|0x0000000C
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress|0x40000000|UINT64|0x00000011
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceSize|0x10000000|UINT64|0x00000012
+
+  gArmJunoTokenSpaceGuid.PcdSynopsysUsbOhciBaseAddress|0x7FFB0000|UINT32|0x00000004
+  gArmJunoTokenSpaceGuid.PcdSynopsysUsbEhciBaseAddress|0x7FFC0000|UINT32|0x00000005
+
+  # Juno Device Trees are loaded from NOR Flash
+  gArmJunoTokenSpaceGuid.PcdJunoFdtDevicePath|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/board.dtb"|VOID*|0x00000008
+
diff --git a/Platform/ARM/JunoPkg/ArmJuno.dsc b/Platform/ARM/JunoPkg/ArmJuno.dsc
index 881d1e67748f..187c9f5602e5 100644
--- a/Platform/ARM/JunoPkg/ArmJuno.dsc
+++ b/Platform/ARM/JunoPkg/ArmJuno.dsc
@@ -36,11 +36,10 @@ [Defines]
 [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
   ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
-  ArmPlatformLib|ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
+  ArmPlatformLib|Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
   ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
 
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
+  NorFlashPlatformLib|Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
 
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
@@ -71,7 +70,6 @@ [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, Libr
   PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
 
 [BuildOptions]
-  *_*_*_PLATFORM_FLAGS = -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmJunoPkg/Include
   GCC:*_*_ARM_PLATFORM_FLAGS = -march=armv8-a
 
 ################################################################################
@@ -333,7 +331,7 @@ [Components.common]
   #
   # Juno platform driver
   #
-  ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+  Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
 
   #
   # SMBIOS/DMI
diff --git a/Platform/ARM/JunoPkg/ArmJuno.fdf b/Platform/ARM/JunoPkg/ArmJuno.fdf
index 527e131de5a4..bb78e1fa8589 100644
--- a/Platform/ARM/JunoPkg/ArmJuno.fdf
+++ b/Platform/ARM/JunoPkg/ArmJuno.fdf
@@ -208,7 +208,7 @@ [FV.FvMain]
   #
   # Juno platform driver
   #
-  INF ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+  INF Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
 
   #
   # SMBIOS/DMI
diff --git a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/AcpiTables.c b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/AcpiTables.c
new file mode 100644
index 000000000000..bf0834643411
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/AcpiTables.c
@@ -0,0 +1,78 @@
+/** @file
+
+  This file contains support for ACPI Tables that are generated at boot time.
+
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "ArmPlatform.h"
+#include "ArmJunoDxeInternal.h"
+
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+
+/*
+ * Memory Mapped Configuration Space Access Table (MCFG)
+ */
+typedef struct {
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER                        Header;
+  EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE Entry;
+} MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE;
+
+MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE mAcpiMcfgTable = {
+    {
+        ARM_ACPI_HEADER (
+          EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+          MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE,
+          EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION
+        ),
+        0, // Reserved
+    }, {
+        FixedPcdGet32 (PcdPciConfigurationSpaceBaseAddress),
+        0, // PciSegmentGroupNumber
+        FixedPcdGet32 (PcdPciBusMin),
+        FixedPcdGet32 (PcdPciBusMax),
+        0 // Reserved;
+    }
+};
+
+/**
+ * Callback called when ACPI Protocol is installed
+ */
+VOID
+AcpiPciNotificationEvent (
+  IN  EFI_EVENT                Event,
+  IN  VOID                     *Context
+  )
+{
+  EFI_STATUS                Status;
+  EFI_ACPI_TABLE_PROTOCOL   *AcpiTableProtocol;
+  UINTN                     AcpiTableKey;
+
+  //
+  // Ensure the ACPI protocol is installed
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID**)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Install MCFG Table
+  //
+  AcpiTableKey = 0;
+  Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, &mAcpiMcfgTable, sizeof (mAcpiMcfgTable), &AcpiTableKey);
+  ASSERT_EFI_ERROR (Status);
+}
diff --git a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
new file mode 100644
index 000000000000..18491c737852
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
@@ -0,0 +1,550 @@
+/** @file
+*
+*  Copyright (c) 2013-2015, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "ArmJunoDxeInternal.h"
+#include <ArmPlatform.h>
+
+#include <IndustryStandard/Pci.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+
+#include <Library/ArmShellCmdLib.h>
+#include <Library/AcpiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+
+
+// This GUID must match the FILE_GUID in ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
+STATIC CONST EFI_GUID mJunoAcpiTableFile = { 0xa1dd808e, 0x1e95, 0x4399, { 0xab, 0xc0, 0x65, 0x3c, 0x82, 0xe8, 0x53, 0x0c } };
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      AcpiDevicePath;
+  PCI_DEVICE_PATH           PciDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciRootComplexDevicePath = {
+    {
+      { ACPI_DEVICE_PATH,
+        ACPI_DP,
+        { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+          (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) }
+      },
+      EISA_PNP_ID (0x0A03),
+      0
+    },
+    {
+      { HARDWARE_DEVICE_PATH,
+        HW_PCI_DP,
+        { (UINT8) (sizeof (PCI_DEVICE_PATH)),
+          (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) }
+      },
+      0,
+      0
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      { END_DEVICE_PATH_LENGTH, 0 }
+    }
+};
+
+EFI_EVENT mAcpiRegistration = NULL;
+
+/**
+  This function reads PCI ID of the controller.
+
+  @param[in]  PciIo   PCI IO protocol handle
+  @param[in]  PciId   Looking for specified PCI ID Vendor/Device
+**/
+STATIC
+EFI_STATUS
+ReadMarvellYoukonPciId (
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN UINT32               PciId
+  )
+{
+  UINT32      DevicePciId;
+  EFI_STATUS  Status;
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint32,
+                        PCI_VENDOR_ID_OFFSET,
+                        1,
+                        &DevicePciId);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (DevicePciId != PciId) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function searches for Marvell Yukon NIC on the Juno
+  platform and returns PCI IO protocol handle for the controller.
+
+  @param[out]  PciIo   PCI IO protocol handle
+**/
+STATIC
+EFI_STATUS
+GetMarvellYukonPciIoProtocol (
+  OUT EFI_PCI_IO_PROTOCOL  **PciIo
+  )
+{
+  UINTN       HandleCount;
+  EFI_HANDLE  *HandleBuffer;
+  UINTN       HIndex;
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer);
+  if (EFI_ERROR (Status)) {
+    return (Status);
+  }
+
+  for (HIndex = 0; HIndex < HandleCount; ++HIndex) {
+    // If PciIo opened with EFI_OPEN_PROTOCOL_GET_PROTOCOL, the CloseProtocol() is not required
+    Status = gBS->OpenProtocol (
+                    HandleBuffer[HIndex],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **) PciIo,
+                    NULL,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    Status = ReadMarvellYoukonPciId (*PciIo, JUNO_MARVELL_YUKON_ID);
+    if (EFI_ERROR (Status)) {
+      continue;
+    } else {
+      break;
+    }
+  }
+
+  gBS->FreePool (HandleBuffer);
+
+  return Status;
+}
+
+/**
+ This function restore the original controller attributes
+
+   @param[in]   PciIo               PCI IO protocol handle
+   @param[in]   PciAttr             PCI controller attributes.
+   @param[in]   AcpiResDescriptor   ACPI 2.0 resource descriptors for the BAR
+**/
+STATIC
+VOID
+RestorePciDev (
+  IN EFI_PCI_IO_PROTOCOL                *PciIo,
+  IN UINT64                             PciAttr
+  )
+{
+  PciIo->Attributes (
+           PciIo,
+           EfiPciIoAttributeOperationSet,
+           PciAttr,
+           NULL
+           );
+}
+
+/**
+ This function returns PCI MMIO base address for a controller
+
+   @param[in]   PciIo               PCI IO protocol handle
+   @param[out]  PciRegBase          PCI base MMIO address
+**/
+STATIC
+EFI_STATUS
+BarIsDeviceMemory (
+  IN   EFI_PCI_IO_PROTOCOL *PciIo,
+  OUT  UINT32              *PciRegBase
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *AcpiResDescriptor;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *AcpiCurrentDescriptor;
+
+  // Marvell Yukon's Bar0 provides base memory address for control registers
+  Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX0, NULL, (VOID**)&AcpiResDescriptor);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  AcpiCurrentDescriptor = AcpiResDescriptor;
+
+  // Search for a memory type descriptor
+  while (AcpiCurrentDescriptor->Desc != ACPI_END_TAG_DESCRIPTOR) {
+
+    // Check if Bar is memory type one and fetch a base address
+    if (AcpiCurrentDescriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR &&
+        AcpiCurrentDescriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM &&
+        !(AcpiCurrentDescriptor->SpecificFlag & ACPI_SPECFLAG_PREFETCHABLE)) {
+      *PciRegBase = AcpiCurrentDescriptor->AddrRangeMin;
+      break;
+    } else {
+      Status = EFI_UNSUPPORTED;
+    }
+
+    AcpiCurrentDescriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (AcpiCurrentDescriptor + 1);
+  }
+
+  gBS->FreePool (AcpiResDescriptor);
+
+  return Status;
+}
+
+/**
+ This function provides PCI MMIO base address, old PCI controller attributes.
+
+   @param[in]   PciIo               PCI IO protocol handle
+   @param[out]  PciRegBase          PCI base MMIO address
+   @param[out]  OldPciAttr          Old PCI controller attributes.
+**/
+STATIC
+EFI_STATUS
+InitPciDev (
+  IN EFI_PCI_IO_PROTOCOL                 *PciIo,
+  OUT UINT32                             *PciRegBase,
+  OUT UINT64                             *OldPciAttr
+  )
+{
+  UINT64      AttrSupports;
+  EFI_STATUS  Status;
+
+  // Get controller's current attributes
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationGet,
+                    0,
+                    OldPciAttr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Fetch supported attributes
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationSupported,
+                    0,
+                    &AttrSupports);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Enable EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_MEMORY and
+  // EFI_PCI_IO_ATTRIBUTE_BUS_MASTER bits in the PCI Config Header
+  AttrSupports &= EFI_PCI_DEVICE_ENABLE;
+  Status = PciIo->Attributes (
+                    PciIo,
+                    EfiPciIoAttributeOperationEnable,
+                    AttrSupports,
+                    NULL);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = BarIsDeviceMemory (PciIo, PciRegBase);
+  if (EFI_ERROR (Status)) {
+    RestorePciDev (PciIo, *OldPciAttr);
+  }
+
+  return Status;
+}
+
+/**
+ This function reads MAC address from IOFPGA and writes it to Marvell Yukon NIC
+
+   @param[in]   PciRegBase   PCI base MMIO address
+**/
+STATIC
+EFI_STATUS
+WriteMacAddress (
+  IN UINT32  PciRegBase
+  )
+{
+  UINT32  MacHigh;
+  UINT32  MacLow;
+
+  // Read MAC address from IOFPGA
+  MacHigh= MmioRead32 (ARM_JUNO_SYS_PCIGBE_H);
+  MacLow = MmioRead32 (ARM_JUNO_SYS_PCIGBE_L);
+
+  // Set software reset control register to protect from deactivation
+  // the config write state
+  MmioWrite16 (PciRegBase + R_CONTROL_STATUS, CS_RESET_CLR);
+
+  // Convert to Marvell MAC Address register format
+  MacHigh = SwapBytes32 ((MacHigh & 0xFFFF) << 16 |
+                         (MacLow & 0xFFFF0000) >> 16);
+  MacLow = SwapBytes32 (MacLow) >> 16;
+
+  // Set MAC Address
+  MmioWrite8 (PciRegBase + R_TST_CTRL_1, TST_CFG_WRITE_ENABLE);
+  MmioWrite32 (PciRegBase + R_MAC, MacHigh);
+  MmioWrite32 (PciRegBase + R_MAC_MAINT, MacHigh);
+  MmioWrite32 (PciRegBase + R_MAC + R_MAC_LOW, MacLow);
+  MmioWrite32 (PciRegBase + R_MAC_MAINT + R_MAC_LOW, MacLow);
+  MmioWrite8 (PciRegBase + R_TST_CTRL_1, TST_CFG_WRITE_DISABLE);
+
+  // Initiate device reset
+  MmioWrite16 (PciRegBase + R_CONTROL_STATUS, CS_RESET_SET);
+  MmioWrite16 (PciRegBase + R_CONTROL_STATUS, CS_RESET_CLR);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The function reads MAC address from Juno IOFPGA registers and writes it
+  into Marvell Yukon NIC.
+**/
+STATIC
+EFI_STATUS
+ArmJunoSetNicMacAddress ()
+{
+  UINT64                              OldPciAttr;
+  EFI_PCI_IO_PROTOCOL*                PciIo;
+  UINT32                              PciRegBase;
+  EFI_STATUS                          Status;
+
+  Status = GetMarvellYukonPciIoProtocol (&PciIo);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  PciRegBase = 0;
+  Status = InitPciDev (PciIo, &PciRegBase, &OldPciAttr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = WriteMacAddress (PciRegBase);
+
+  RestorePciDev (PciIo, OldPciAttr);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Notification function of the event defined as belonging to the
+  EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in
+  the entry point of the driver.
+
+  This function is called when an event belonging to the
+  EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an
+  event is signalled once at the end of the dispatching of all
+  drivers (end of the so called DXE phase).
+
+  @param[in]  Event    Event declared in the entry point of the driver whose
+                       notification function is being invoked.
+  @param[in]  Context  NULL
+**/
+STATIC
+VOID
+OnEndOfDxe (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL* PciRootComplexDevicePath;
+  EFI_HANDLE                Handle;
+  EFI_STATUS                Status;
+
+  //
+  // PCI Root Complex initialization
+  // At the end of the DXE phase, we should get all the driver dispatched.
+  // Force the PCI Root Complex to be initialized. It allows the OS to skip
+  // this step.
+  //
+  PciRootComplexDevicePath = (EFI_DEVICE_PATH_PROTOCOL*) &mPciRootComplexDevicePath;
+  Status = gBS->LocateDevicePath (&gEfiPciRootBridgeIoProtocolGuid,
+                                  &PciRootComplexDevicePath,
+                                  &Handle);
+
+  Status = gBS->ConnectController (Handle, NULL, PciRootComplexDevicePath, FALSE);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = ArmJunoSetNicMacAddress ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ArmJunoDxe: Failed to set Marvell Yukon NIC MAC address\n"));
+  }
+}
+
+EFI_STATUS
+EFIAPI
+ArmJunoEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  HypBase;
+  CHAR16                *TextDevicePath;
+  UINTN                 TextDevicePathSize;
+  VOID                  *Buffer;
+  UINT32                JunoRevision;
+  EFI_EVENT             EndOfDxeEvent;
+
+  //
+  // Register the OHCI and EHCI controllers as non-coherent
+  // non-discoverable devices.
+  //
+  Status = RegisterNonDiscoverableMmioDevice (
+             NonDiscoverableDeviceTypeOhci,
+             NonDiscoverableDeviceDmaTypeNonCoherent,
+             NULL,
+             NULL,
+             1,
+             FixedPcdGet32 (PcdSynopsysUsbOhciBaseAddress),
+             SIZE_64KB
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = RegisterNonDiscoverableMmioDevice (
+             NonDiscoverableDeviceTypeEhci,
+             NonDiscoverableDeviceDmaTypeNonCoherent,
+             NULL,
+             NULL,
+             1,
+             FixedPcdGet32 (PcdSynopsysUsbEhciBaseAddress),
+             SIZE_64KB
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // If a hypervisor has been declared then we need to make sure its region is protected at runtime
+  //
+  // Note: This code is only a workaround for our dummy hypervisor (ArmPkg/Extra/AArch64ToAArch32Shim/)
+  //       that does not set up (yet) the stage 2 translation table to hide its own memory to EL1.
+  //
+  if (FixedPcdGet32 (PcdHypFvSize) != 0) {
+    // Ensure the hypervisor region is strictly contained into a EFI_PAGE_SIZE-aligned region.
+    // The memory must be a multiple of EFI_PAGE_SIZE to ensure we do not reserve more memory than the hypervisor itself.
+    // A UEFI Runtime region size granularity cannot be smaller than EFI_PAGE_SIZE. If the hypervisor size is not rounded
+    // to this size then there is a risk some non-runtime memory could be visible to the OS view.
+    if (((FixedPcdGet32 (PcdHypFvSize) & EFI_PAGE_MASK) == 0) && ((FixedPcdGet32 (PcdHypFvBaseAddress) & EFI_PAGE_MASK) == 0)) {
+      // The memory needs to be declared because the DXE core marked it as reserved and removed it from the memory space
+      // as it contains the Firmware.
+      Status = gDS->AddMemorySpace (
+          EfiGcdMemoryTypeSystemMemory,
+          FixedPcdGet32 (PcdHypFvBaseAddress), FixedPcdGet32 (PcdHypFvSize),
+          EFI_MEMORY_WB | EFI_MEMORY_RUNTIME
+          );
+      if (!EFI_ERROR (Status)) {
+        // We allocate the memory to ensure it is marked as runtime memory
+        HypBase = FixedPcdGet32 (PcdHypFvBaseAddress);
+        Status = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode,
+                                     EFI_SIZE_TO_PAGES (FixedPcdGet32 (PcdHypFvSize)), &HypBase);
+      }
+    } else {
+      // The hypervisor must be contained into a EFI_PAGE_SIZE-aligned region and its size must also be aligned
+      // on a EFI_PAGE_SIZE boundary (ie: 4KB).
+      Status = EFI_UNSUPPORTED;
+      ASSERT_EFI_ERROR (Status);
+    }
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  // Install dynamic Shell command to run baremetal binaries.
+  Status = ShellDynCmdRunAxfInstall (ImageHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "ArmJunoDxe: Failed to install ShellDynCmdRunAxf\n"));
+  }
+
+  GetJunoRevision(JunoRevision);
+
+  //
+  // Try to install the ACPI Tables
+  //
+  Status = LocateAndInstallAcpiFromFv (&mJunoAcpiTableFile);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Setup R1/R2 options if not already done.
+  //
+  if (JunoRevision != JUNO_REVISION_R0) {
+    // Enable PCI enumeration
+    PcdSetBool (PcdPciDisableBusEnumeration, FALSE);
+
+    //
+    // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
+    // The "OnEndOfDxe()" function is declared as the call back function.
+    // It will be called at the end of the DXE phase when an event of the
+    // same group is signalled to inform about the end of the DXE phase.
+    // Install the INSTALL_FDT_PROTOCOL protocol.
+    //
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    OnEndOfDxe,
+                    NULL,
+                    &gEfiEndOfDxeEventGroupGuid,
+                    &EndOfDxeEvent
+                    );
+
+    // Declare the related ACPI Tables
+    EfiCreateProtocolNotifyEvent (
+        &gEfiAcpiTableProtocolGuid,
+        TPL_CALLBACK,
+        AcpiPciNotificationEvent,
+        NULL,
+        &mAcpiRegistration
+        );
+  }
+
+  //
+  // Set up the device path to the FDT.
+  //
+  TextDevicePath = (CHAR16*)FixedPcdGetPtr (PcdJunoFdtDevicePath);
+  if (TextDevicePath != NULL) {
+    TextDevicePathSize = StrSize (TextDevicePath);
+    Buffer = PcdSetPtr (PcdFdtDevicePaths, &TextDevicePathSize, TextDevicePath);
+    Status = (Buffer != NULL) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
+  } else {
+    Status = EFI_NOT_FOUND;
+  }
+
+  if (EFI_ERROR (Status)) {
+    DEBUG (
+      (EFI_D_ERROR,
+      "ArmJunoDxe: Setting of FDT device path in PcdFdtDevicePaths failed - %r\n", Status)
+      );
+    return Status;
+  }
+
+  return Status;
+}
diff --git a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
new file mode 100644
index 000000000000..b215a3bc882d
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
@@ -0,0 +1,88 @@
+#
+#  Copyright (c) 2013-2015, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmJunoDxe
+  FILE_GUID                      = 1484ebe8-2681-45f1-a2e5-12ecad893b62
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ArmJunoEntryPoint
+
+[Sources.common]
+  AcpiTables.c
+  ArmJunoDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/ARM/JunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+  AcpiLib
+  ArmLib
+  ArmShellCmdRunAxfLib
+  BaseMemoryLib
+  DebugLib
+  DxeServicesTableLib
+  IoLib
+  NonDiscoverableDeviceRegistrationLib
+  PcdLib
+  PrintLib
+  SerialPortLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+  UefiDriverEntryPoint
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gEfiFileInfoGuid
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiDevicePathFromTextProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
+  gEfiAcpiTableProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+  gArmTokenSpaceGuid.PcdHypFvBaseAddress
+  gArmTokenSpaceGuid.PcdHypFvSize
+
+  gArmJunoTokenSpaceGuid.PcdSynopsysUsbEhciBaseAddress
+  gArmJunoTokenSpaceGuid.PcdSynopsysUsbOhciBaseAddress
+
+  gArmJunoTokenSpaceGuid.PcdJunoFdtDevicePath
+
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument
+
+  # PCI Root complex specific PCDs
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
+  gArmTokenSpaceGuid.PcdPciBusMin
+  gArmTokenSpaceGuid.PcdPciBusMax
+
+[Pcd]
+  gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+
+[Depex]
+  # We depend on these protocols to create the default boot entries
+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h
new file mode 100644
index 000000000000..5d2b68fabd12
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h
@@ -0,0 +1,54 @@
+/** @file
+*
+*  Copyright (c) 2013-2015, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __ARM_JUNO_DXE_INTERNAL_H__
+#define __ARM_JUNO_DXE_INTERNAL_H__
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/ArmLib.h>
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/AcpiTable.h>
+
+#include <IndustryStandard/Acpi.h>
+
+#define ACPI_SPECFLAG_PREFETCHABLE    0x06
+#define JUNO_MARVELL_YUKON_ID         0x438011AB /* Juno Marvell PCI Dev ID */
+#define TST_CFG_WRITE_ENABLE          0x02       /* Enable Config Write */
+#define TST_CFG_WRITE_DISABLE         0x00       /* Disable Config Write */
+#define CS_RESET_CLR                  0x02       /* SW Reset Clear */
+#define CS_RESET_SET                  0x00       /* SW Reset Set */
+#define R_CONTROL_STATUS              0x0004     /* Control/Status Register */
+#define R_MAC                         0x0100     /* MAC Address */
+#define R_MAC_MAINT                   0x0110     /* MAC Address Maintenance */
+#define R_MAC_LOW                     0x04       /* MAC Address Low Register Offset */
+#define R_TST_CTRL_1                  0x0158     /* Test Control Register 1 */
+
+
+/**
+ * Callback called when ACPI Protocol is installed
+ */
+VOID
+AcpiPciNotificationEvent (
+  IN  EFI_EVENT                Event,
+  IN  VOID                     *Context
+  );
+
+#endif // __ARM_JUNO_DXE_INTERNAL_H__
diff --git a/Platform/ARM/JunoPkg/Include/ArmPlatform.h b/Platform/ARM/JunoPkg/Include/ArmPlatform.h
new file mode 100644
index 000000000000..399fd952791f
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Include/ArmPlatform.h
@@ -0,0 +1,180 @@
+/** @file
+*
+*  Copyright (c) 2013-2017, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __ARM_JUNO_H__
+#define __ARM_JUNO_H__
+
+//#include <VExpressMotherBoard.h>
+
+/***********************************************************************************
+// Platform Memory Map
+************************************************************************************/
+
+// Motherboard Peripheral and On-chip peripheral
+#define ARM_VE_BOARD_PERIPH_BASE              0x1C010000
+#define ARM_VE_BOARD_SYS_ID                   0x0000
+#define ARM_VE_BOARD_SYS_PCIE_GBE_L           0x0074
+#define ARM_VE_BOARD_SYS_PCIE_GBE_H           0x0078
+
+#define ARM_VE_BOARD_SYS_ID_REV(word)         ((word >> 28) & 0xff)
+
+// NOR Flash 0
+#define ARM_VE_SMB_NOR0_BASE                  0x08000000
+#define ARM_VE_SMB_NOR0_SZ                    SIZE_64MB
+
+// Off-Chip peripherals (USB, Ethernet, VRAM)
+#define ARM_VE_SMB_PERIPH_BASE                0x18000000
+#define ARM_VE_SMB_PERIPH_SZ                  (SIZE_64MB + SIZE_2MB)
+
+// On-Chip non-secure ROM
+#define ARM_JUNO_NON_SECURE_ROM_BASE          0x1F000000
+#define ARM_JUNO_NON_SECURE_ROM_SZ            SIZE_16MB
+
+// On-Chip Peripherals
+#define ARM_JUNO_PERIPHERALS_BASE             0x20000000
+#define ARM_JUNO_PERIPHERALS_SZ               0x0E000000
+
+// PCIe MSI address window
+#define ARM_JUNO_GIV2M_MSI_BASE               0x2c1c0000
+#define ARM_JUNO_GIV2M_MSI_SZ                 SIZE_256KB
+
+// PCIe MSI to SPI mapping range
+#define ARM_JUNO_GIV2M_MSI_SPI_BASE           224
+#define ARM_JUNO_GIV2M_MSI_SPI_COUNT          127 //TRM says last SPI is 351, 351-224=127
+
+// On-Chip non-secure SRAM
+#define ARM_JUNO_NON_SECURE_SRAM_BASE         0x2E000000
+#define ARM_JUNO_NON_SECURE_SRAM_SZ           SIZE_16MB
+
+// SOC peripherals (HDLCD, UART, I2C, I2S, USB, SMC-PL354, etc)
+#define ARM_JUNO_SOC_PERIPHERALS_BASE         0x7FF50000
+#define ARM_JUNO_SOC_PERIPHERALS_SZ           (SIZE_64KB * 9)
+
+// 6GB of DRAM from the 64bit address space
+#define ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE     0x0880000000
+#define ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ       (SIZE_2GB + SIZE_4GB)
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_ARM_OEM_ID           'A','R','M','L','T','D'   // OEMID 6 bytes long
+#define EFI_ACPI_ARM_OEM_TABLE_ID     SIGNATURE_64('A','R','M','-','J','U','N','O') // OEM table id 8 bytes long
+#define EFI_ACPI_ARM_OEM_REVISION     0x20140727
+#define EFI_ACPI_ARM_CREATOR_ID       SIGNATURE_32('A','R','M',' ')
+#define EFI_ACPI_ARM_CREATOR_REVISION 0x00000099
+
+// A macro to initialise the common header part of EFI ACPI tables as defined by
+// EFI_ACPI_DESCRIPTION_HEADER structure.
+#define ARM_ACPI_HEADER(Signature, Type, Revision) {              \
+    Signature,                      /* UINT32  Signature */       \
+    sizeof (Type),                  /* UINT32  Length */          \
+    Revision,                       /* UINT8   Revision */        \
+    0,                              /* UINT8   Checksum */        \
+    { EFI_ACPI_ARM_OEM_ID },        /* UINT8   OemId[6] */        \
+    EFI_ACPI_ARM_OEM_TABLE_ID,      /* UINT64  OemTableId */      \
+    EFI_ACPI_ARM_OEM_REVISION,      /* UINT32  OemRevision */     \
+    EFI_ACPI_ARM_CREATOR_ID,        /* UINT32  CreatorId */       \
+    EFI_ACPI_ARM_CREATOR_REVISION   /* UINT32  CreatorRevision */ \
+  }
+
+//
+// Hardware platform identifiers
+//
+#define JUNO_REVISION_PROTOTYPE 0
+#define JUNO_REVISION_R0        1
+#define JUNO_REVISION_R1        2
+#define JUNO_REVISION_R2        3
+#define JUNO_REVISION_UKNOWN    0xFF
+
+//
+// We detect whether we are running on a Juno r0, r1 or r2
+// board at runtime by checking the value of board SYS_ID
+//
+#define GetJunoRevision(JunoRevision)                                  \
+{                                                                      \
+  UINT32    SysId;                                                     \
+  SysId = MmioRead32 (ARM_VE_BOARD_PERIPH_BASE+ARM_VE_BOARD_SYS_ID);   \
+  JunoRevision = ARM_VE_BOARD_SYS_ID_REV( SysId );                     \
+}
+
+
+// Define if the exported ACPI Tables are based on ACPI 5.0 spec or latest
+//#define ARM_JUNO_ACPI_5_0
+
+//
+// Address of the system registers that contain the MAC address
+// assigned to the PCI Gigabyte Ethernet device.
+//
+
+#define ARM_JUNO_SYS_PCIGBE_L  (ARM_VE_BOARD_PERIPH_BASE + ARM_VE_BOARD_SYS_PCIE_GBE_L)
+#define ARM_JUNO_SYS_PCIGBE_H  (ARM_VE_BOARD_PERIPH_BASE + ARM_VE_BOARD_SYS_PCIE_GBE_H)
+
+/***********************************************************************************
+// Motherboard memory-mapped peripherals
+************************************************************************************/
+
+// Define MotherBoard SYS flags offsets (from ARM_VE_BOARD_PERIPH_BASE)
+#define ARM_VE_SYS_ID_REG                   (ARM_VE_BOARD_PERIPH_BASE + 0x00000)
+#define ARM_VE_SYS_SW_REG                   (ARM_VE_BOARD_PERIPH_BASE + 0x00004)
+#define ARM_VE_SYS_LED_REG                  (ARM_VE_BOARD_PERIPH_BASE + 0x00008)
+#define ARM_VE_SYS_FLAGS_REG                (ARM_VE_BOARD_PERIPH_BASE + 0x00030)
+#define ARM_VE_SYS_FLAGS_SET_REG            (ARM_VE_BOARD_PERIPH_BASE + 0x00030)
+#define ARM_VE_SYS_FLAGS_CLR_REG            (ARM_VE_BOARD_PERIPH_BASE + 0x00034)
+#define ARM_VE_SYS_FLAGS_NV_REG             (ARM_VE_BOARD_PERIPH_BASE + 0x00038)
+#define ARM_VE_SYS_FLAGS_NV_SET_REG         (ARM_VE_BOARD_PERIPH_BASE + 0x00038)
+#define ARM_VE_SYS_FLAGS_NV_CLR_REG         (ARM_VE_BOARD_PERIPH_BASE + 0x0003C)
+#define ARM_VE_SYS_FLASH                    (ARM_VE_BOARD_PERIPH_BASE + 0x0004C)
+#define ARM_VE_SYS_CFGSWR_REG               (ARM_VE_BOARD_PERIPH_BASE + 0x00058)
+#define ARM_VE_SYS_MISC                     (ARM_VE_BOARD_PERIPH_BASE + 0x00060)
+#define ARM_VE_SYS_PROCID0_REG              (ARM_VE_BOARD_PERIPH_BASE + 0x00084)
+#define ARM_VE_SYS_PROCID1_REG              (ARM_VE_BOARD_PERIPH_BASE + 0x00088)
+#define ARM_VE_SYS_CFGDATA_REG              (ARM_VE_BOARD_PERIPH_BASE + 0x000A0)
+#define ARM_VE_SYS_CFGCTRL_REG              (ARM_VE_BOARD_PERIPH_BASE + 0x000A4)
+#define ARM_VE_SYS_CFGSTAT_REG              (ARM_VE_BOARD_PERIPH_BASE + 0x000A8)
+
+//
+// Sites where the peripheral is fitted
+//
+#define ARM_VE_UNSUPPORTED                        ~0
+#define ARM_VE_MOTHERBOARD_SITE                   0
+#define ARM_VE_DAUGHTERBOARD_1_SITE               1
+#define ARM_VE_DAUGHTERBOARD_2_SITE               2
+
+#define VIRTUAL_SYS_CFG(site,func)                (((site) << 24) | (func))
+
+//
+// System Configuration Control Functions
+//
+#define SYS_CFG_OSC           1
+#define SYS_CFG_VOLT          2
+#define SYS_CFG_AMP           3
+#define SYS_CFG_TEMP          4
+#define SYS_CFG_RESET         5
+#define SYS_CFG_SCC           6
+#define SYS_CFG_MUXFPGA       7
+#define SYS_CFG_SHUTDOWN      8
+#define SYS_CFG_REBOOT        9
+#define SYS_CFG_DVIMODE       11
+#define SYS_CFG_POWER         12
+// Oscillator for Site 1
+#define SYS_CFG_OSC_SITE1     VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_1_SITE, \
+                                              SYS_CFG_OSC)
+// Oscillator for Site 2
+#define SYS_CFG_OSC_SITE2     VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_2_SITE, \
+                                              SYS_CFG_OSC)
+// Can not access the battery backed-up hardware clock on the
+// Versatile Express motherboard
+#define SYS_CFG_RTC           VIRTUAL_SYS_CFG(ARM_VE_UNSUPPORTED,1)
+
+#endif
diff --git a/Platform/ARM/JunoPkg/Library/ArmJunoLib/AArch64/ArmJunoHelper.S b/Platform/ARM/JunoPkg/Library/ArmJunoLib/AArch64/ArmJunoHelper.S
new file mode 100644
index 000000000000..4bdf08d1a98a
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/ArmJunoLib/AArch64/ArmJunoHelper.S
@@ -0,0 +1,58 @@
+/** @file
+*
+*  Copyright (c) 2013-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 2) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+  and   x1, x0, #ARM_CORE_MASK
+  and   x0, x0, #ARM_CLUSTER_MASK
+  add   x0, x1, x0, LSR #7
+  ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  ldr   w0, PrimaryCoreMpid
+  ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+  MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCoreMask))
+  and   x0, x0, x1
+
+  ldr   w1, PrimaryCoreMpid
+
+  cmp   w0, w1
+  cset  x0, eq
+  ret
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  // The trusted firmware passes the primary CPU MPID through x0 register.
+  // Save it in a variable.
+  adr  x1, PrimaryCoreMpid
+  str  w0, [x1]
+  ret
+
+PrimaryCoreMpid:  .word    0x0
diff --git a/Platform/ARM/JunoPkg/Library/ArmJunoLib/Arm/ArmJunoHelper.S b/Platform/ARM/JunoPkg/Library/ArmJunoLib/Arm/ArmJunoHelper.S
new file mode 100644
index 000000000000..a7e904eac697
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/ArmJunoLib/Arm/ArmJunoHelper.S
@@ -0,0 +1,91 @@
+/** @file
+*
+*  Copyright (c) 2013-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <AsmMacroIoLib.h>
+#include <Library/ArmLib.h>
+
+//
+// Return the core position from the value of its MpId register
+//
+// This function returns the core position from the position 0 in the processor.
+// This function might be called from assembler before any stack is set.
+//
+// @return   Return the core position
+//
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 2) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+  and   r1, r0, #ARM_CORE_MASK
+  and   r0, r0, #ARM_CLUSTER_MASK
+  add   r0, r1, r0, LSR #7
+  bx    lr
+
+//
+// Return the MpId of the primary core
+//
+// This function returns the MpId of the primary core.
+// This function might be called from assembler before any stack is set.
+//
+// @return   Return the MpId of the primary core
+//
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  LDRL  (r0, PrimaryCoreMpid)
+  bx    lr
+
+//
+// Return a non-zero value if the callee is the primary core
+//
+// This function returns a non-zero value if the callee is the primary core.
+// The primary core is the core responsible to initialize the hardware and run UEFI.
+// This function might be called from assembler before any stack is set.
+//
+//  @return   Return a non-zero value if the callee is the primary core.
+//
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+  MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCoreMask))
+  and   r0, r0, r1
+
+  LDRL  (r1, PrimaryCoreMpid)
+
+  cmp   r0, r1
+  moveq r0, #1
+  movne r0, #0
+  bx    lr
+
+//
+// First platform specific function to be called in the PEI phase
+//
+// This function is actually the first function called by the PrePi
+// or PrePeiCore modules. It allows to retrieve arguments passed to
+// the UEFI firmware through the CPU registers.
+//
+ASM_FUNC(ArmPlatformPeiBootAction)
+  // The trusted firmware passes the primary CPU MPID through r0 register.
+  // Save it in a variable.
+  adr  r1, PrimaryCoreMpid
+  str  r0, [r1]
+  bx   lr
+
+PrimaryCoreMpid:  .word    0x0
diff --git a/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJuno.c b/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJuno.c
new file mode 100644
index 000000000000..4a57ec5517ec
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJuno.c
@@ -0,0 +1,193 @@
+/** @file
+*
+*  Copyright (c) 2013-2016, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Drivers/PL011Uart.h>
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include <ArmPlatform.h>
+
+ARM_CORE_INFO mJunoInfoTable[] = {
+  {
+    // Cluster 0, Core 0
+    0x0, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 1
+    0x0, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 0
+    0x1, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 1
+    0x1, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 2
+    0x1, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 3
+    0x1, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  }
+};
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+  @return   Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  Initialize controllers that must setup in the normal world
+
+  This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+  in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  RETURN_STATUS       Status;
+  UINT64              BaudRate;
+  UINT32              ReceiveFifoDepth;
+  EFI_PARITY_TYPE     Parity;
+  UINT8               DataBits;
+  EFI_STOP_BITS_TYPE  StopBits;
+
+  Status = RETURN_SUCCESS;
+
+  //
+  // Initialize the Serial Debug UART
+  //
+  if (FixedPcdGet64 (PcdSerialDbgRegisterBase)) {
+    ReceiveFifoDepth = 0; // Use the default value for FIFO depth
+    Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
+    DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
+    StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
+
+    BaudRate = (UINTN)FixedPcdGet64 (PcdSerialDbgUartBaudRate);
+    Status = PL011UartInitializePort (
+               (UINTN)FixedPcdGet64 (PcdSerialDbgRegisterBase),
+               FixedPcdGet32 (PcdSerialDbgUartClkInHz),
+               &BaudRate,
+               &ReceiveFifoDepth,
+               &Parity,
+               &DataBits,
+               &StopBits
+               );
+  }
+
+  return Status;
+}
+
+/**
+  Initialize the system (or sometimes called permanent) memory
+
+  This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+  VOID
+  )
+{
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN                   *CoreCount,
+  OUT ARM_CORE_INFO           **ArmCoreTable
+  )
+{
+  // Only support one cluster
+  *CoreCount    = sizeof(mJunoInfoTable) / sizeof(ARM_CORE_INFO);
+  *ArmCoreTable = mJunoInfoTable;
+  return EFI_SUCCESS;
+}
+
+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/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf b/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
new file mode 100644
index 000000000000..2dd384daba3d
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
@@ -0,0 +1,80 @@
+#
+#  Copyright (c) 2013-2016, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmJunoLib
+  FILE_GUID                      = 87c525cd-e1a2-469e-994c-c28cd0c7bd0d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Platform/ARM/JunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  HobLib
+  MemoryAllocationLib
+  SerialPortLib
+
+[Sources.common]
+  ArmJuno.c
+  ArmJunoMem.c
+
+[Sources.AARCH64]
+  AArch64/ArmJunoHelper.S
+
+[Sources.ARM]
+  Arm/ArmJunoHelper.S     | GCC
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+
+  gArmJunoTokenSpaceGuid.PcdPcieControlBaseAddress
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceSize
+
+
+  #
+  # PL011 Serial Debug UART
+  #
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
+
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdPciMmio32Base
+  gArmTokenSpaceGuid.PcdPciMmio32Size
+  gArmTokenSpaceGuid.PcdPciMmio64Base
+  gArmTokenSpaceGuid.PcdPciMmio64Size
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
diff --git a/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoMem.c b/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoMem.c
new file mode 100644
index 000000000000..aa8d7d9c3b0d
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/ArmJunoLib/ArmJunoMem.c
@@ -0,0 +1,173 @@
+/** @file
+*
+*  Copyright (c) 2013-2015, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <ArmPlatform.h>
+
+// The total number of descriptors, including the final "end-of-table" descriptor.
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 16
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+                                    Virtual Memory mapping. This array must be ended by a zero-filled
+                                    entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
+  UINTN                         Index = 0;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  //
+  // Declared the additional 6GB of memory
+  //
+  ResourceAttributes =
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED;
+
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+    ResourceAttributes,
+    ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE,
+    ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ);
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+      return;
+  }
+
+  if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
+      CacheAttributes = DDR_ATTRIBUTES_CACHED;
+  } else {
+      CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+  }
+
+  // SMB CS0 - NOR0 Flash
+  VirtualMemoryTable[Index].PhysicalBase    = ARM_VE_SMB_NOR0_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_NOR0_BASE;
+  VirtualMemoryTable[Index].Length          = SIZE_256KB * 255;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  // Environment Variables region
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255);
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255);
+  VirtualMemoryTable[Index].Length          = SIZE_64KB * 4;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // SMB CS2 & CS3 - Off-chip (motherboard) peripherals
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_SMB_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // Juno OnChip non-secure ROM
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_JUNO_NON_SECURE_ROM_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_JUNO_NON_SECURE_ROM_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_JUNO_NON_SECURE_ROM_SZ;
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // Juno OnChip peripherals
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_JUNO_PERIPHERALS_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_JUNO_PERIPHERALS_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_JUNO_PERIPHERALS_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // Juno OnChip non-secure SRAM
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_JUNO_NON_SECURE_SRAM_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_JUNO_NON_SECURE_SRAM_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_JUNO_NON_SECURE_SRAM_SZ;
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // PCI Root Complex
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdPcieControlBaseAddress);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdPcieControlBaseAddress);
+  VirtualMemoryTable[Index].Length          = SIZE_128KB;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  //
+  // PCI Configuration Space
+  //
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdPciConfigurationSpaceBaseAddress);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdPciConfigurationSpaceBaseAddress);
+  VirtualMemoryTable[Index].Length          = PcdGet64 (PcdPciConfigurationSpaceSize);
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  //
+  // PCI Memory Space
+  //
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet32 (PcdPciMmio32Base);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet32 (PcdPciMmio32Base);
+  VirtualMemoryTable[Index].Length          = PcdGet32 (PcdPciMmio32Size);
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  //
+  // 64-bit PCI Memory Space
+  //
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdPciMmio64Base);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdPciMmio64Base);
+  VirtualMemoryTable[Index].Length          = PcdGet64 (PcdPciMmio64Size);
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // Juno SOC peripherals
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_JUNO_SOC_PERIPHERALS_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_JUNO_SOC_PERIPHERALS_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_JUNO_SOC_PERIPHERALS_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // DDR - 2GB
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length          = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // DDR - 6GB
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ;
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase  = 0;
+  VirtualMemoryTable[Index].VirtualBase     = 0;
+  VirtualMemoryTable[Index].Length          = 0;
+  VirtualMemoryTable[Index].Attributes      = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf
index 68e22396ccef..8f68f4b4f251 100644
--- a/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf
+++ b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf
@@ -35,10 +35,10 @@ [Sources]
   XPressRich3.c
 
 [Packages]
-  ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
   ArmPkg/ArmPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
+  Platform/ARM/JunoPkg/ArmJuno.dec
 
 [LibraryClasses]
   BaseLib
diff --git a/Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c b/Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c
new file mode 100644
index 000000000000..b31b9635b7b7
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c
@@ -0,0 +1,68 @@
+/** @file
+
+ Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NorFlashPlatformLib.h>
+#include <ArmPlatform.h>
+
+NOR_FLASH_DESCRIPTION mNorFlashDevices[] = {
+  {
+    ARM_VE_SMB_NOR0_BASE,
+    ARM_VE_SMB_NOR0_BASE,
+    SIZE_256KB * 255,
+    SIZE_256KB,
+    {0xE7223039, 0x5836, 0x41E1, { 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59} }
+  },
+  {
+    ARM_VE_SMB_NOR0_BASE,
+    ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255,
+    SIZE_64KB * 4,
+    SIZE_64KB,
+    {0x02118005, 0x9DA7, 0x443A, { 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB } }
+  },
+};
+
+EFI_STATUS
+NorFlashPlatformInitialization (
+  VOID
+  )
+{
+  // Everything seems ok so far, so now we need to disable the platform-specific
+  // flash write protection for Versatile Express
+  if ((MmioRead32 (ARM_VE_SYS_FLASH) & 0x1) == 0) {
+    // Writing to NOR FLASH is disabled, so enable it
+    MmioWrite32 (ARM_VE_SYS_FLASH, 1);
+    DEBUG((DEBUG_BLKIO, "NorFlashPlatformInitialization: informational - Had to enable HSYS_FLASH flag.\n" ));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashPlatformGetDevices (
+  OUT NOR_FLASH_DESCRIPTION   **NorFlashDevices,
+  OUT UINT32                  *Count
+  )
+{
+  if ((NorFlashDevices == NULL) || (Count == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *NorFlashDevices = mNorFlashDevices;
+  *Count = sizeof (mNorFlashDevices) / sizeof (NOR_FLASH_DESCRIPTION);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf b/Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
new file mode 100644
index 000000000000..881a479d85e8
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
@@ -0,0 +1,33 @@
+#/** @file
+#
+#  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = NorFlashJunoLib
+  FILE_GUID                      = 3eb6cbc4-ce95-11e2-b1bd-00241d0c1ba8
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NorFlashPlatformLib
+
+[Sources.common]
+  NorFlashJuno.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/JunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
diff --git a/Platform/ARM/JunoPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/ARM/JunoPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
index 457e1ff552d2..a8305925cd2d 100644
--- a/Platform/ARM/JunoPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+++ b/Platform/ARM/JunoPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -35,9 +35,9 @@ [Sources]
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
-  ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
+  Platform/ARM/JunoPkg/ArmJuno.dec
 
 [LibraryClasses]
   ArmLib
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
index efa41165e4ad..5db6731ec9ec 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -55,6 +55,18 @@ [LibraryClasses.common]
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
   ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
 
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
+
+[LibraryClasses.ARM]
+  #
+  # PSCI support in EL3 may not be available if we are not running under a PSCI
+  # compliant secure firmware. Assume PSCI on AARCH64, and fall back to the
+  # syscfg MMIO register implementation on ARM.
+  # This will not work at actual runtime.
+  #
+  ResetSystemLib|ArmPlatformPkg/ArmVExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
+
 [BuildOptions]
 !ifdef ARM_BIGLITTLE_TC2
   *_*_ARM_ARCHCC_FLAGS  = -DARM_BIGLITTLE_TC2=1
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
index fc628ad08c9e..e02a78a9766c 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
@@ -61,6 +61,9 @@ [LibraryClasses.common]
 
   DtPlatformDtbLoaderLib|Platform/ARM/VExpressPkg/Library/ArmVExpressDtPlatformDtbLoaderLib/ArmVExpressDtPlatformDtbLoaderLib.inf
 
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
+
 [LibraryClasses.common.SEC]
   ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
 
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 3db269086d5b..203a781d9bd5 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -234,21 +234,11 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
   ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
 !if $(SECURE_BOOT_ENABLE) == TRUE
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
 !endif
 
-[LibraryClasses.ARM]
-  #
-  # PSCI support in EL3 may not be available if we are not running under a PSCI
-  # compliant secure firmware. Assume PSCI on AARCH64, and fall back to the
-  # syscfg MMIO register implementation on ARM.
-  # This will not work at actual runtime.
-  #
-  ResetSystemLib|ArmPlatformPkg/ArmVExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
-
 [LibraryClasses.ARM, LibraryClasses.AARCH64]
   #
   # It is not possible to prevent the ARM compiler for generic intrinsic functions.
-- 
2.11.0



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

* [PATCH edk2-platforms v2 06/13] Platform/ARM/VExpress: import VExpressPkg from EDK2
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (4 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 05/13] Platform/ARM/Juno: import ArmJunoPkg from EDK2 Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 07/13] Platform/ARM: remove outdated SP804 TimerLib reference Ard Biesheuvel
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Import the pieces that are closely tied to the ARM Versatile Express
development platforms into edk2-platforms, so they can be removed from
upstream EDK2.

Note that this includes the LCD drivers, and the ArmPlatformSysConfigLib
library class, which is not used anywhere else.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
Note that this omits the CTA9x4 code, which is not used anymore.

 Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf                                                 |   3 +-
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc                                                  |  27 +-
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf                                                  |  10 +-
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc                                               |  17 +-
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf                                               |   2 +-
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc                                                       |   8 +-
 Platform/ARM/VExpressPkg/ArmVExpressPkg.dec                                                        |  53 ++
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c                                        |  90 ++
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf                                      |  39 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c                                         |  38 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf                                       |  37 +
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c                      | 519 ++++++++++++
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf                 |  51 ++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c                                      | 133 +++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf                   |  63 ++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c                       | 882 ++++++++++++++++++++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c                       | 393 +++++++++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h                       | 128 +++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c                                   | 126 +++
 Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf                |  59 ++
 Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h                                                   |  89 ++
 Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h                                                | 149 ++++
 Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h                                 |  63 ++
 Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h                                          | 221 +++++
 Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h                                   | 154 ++++
 Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h                                       |  79 ++
 Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h                                             | 140 ++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf                         |  54 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c                                 | 195 +++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S                           |  81 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm                         |  96 +++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c                              | 182 ++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S                           |  61 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S                               |  97 +++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm                             | 118 +++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf                             |  63 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf                          |  59 ++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c                                         | 209 +++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c                                      | 161 ++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c                    | 273 ++++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf               |  35 +
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c   | 283 +++++++
 Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf |  37 +
 Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c                            | 285 +++++++
 Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf                       |  45 +
 Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c                      |  84 ++
 Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf                 |  33 +
 Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c                      | 370 ++++++++
 Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf                 |  44 +
 Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c                                   | 111 +++
 Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf                                 |  36 +
 51 files changed, 6550 insertions(+), 35 deletions(-)

diff --git a/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf b/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf
index cc0f06f53323..35685274a041 100644
--- a/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf
+++ b/Platform/ARM/VExpressPkg/AcpiTables/AcpiTables.inf
@@ -31,11 +31,10 @@ [Sources]
 [Packages]
   ArmPkg/ArmPkg.dec
   ArmPlatformPkg/ArmPlatformPkg.dec
-  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
-
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
 
 [FixedPcd]
   gArmTokenSpaceGuid.PcdGicDistributorBase
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
index 5db6731ec9ec..51da85fe8bc0 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -40,23 +40,22 @@ [Defines]
 [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
   ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
-  ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
+  ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
 
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+  ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
 
-  #DebugAgentTimerLib|ArmPlatformPkg/ArmVExpressPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
+  #DebugAgentTimerLib|Platform/ARM/VExpressPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
 
   # ARM General Interrupt Driver in Secure and Non-secure
   ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
 
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
+  LcdPlatformLib|Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
 
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
   ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
 
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
+  ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
 
 [LibraryClasses.ARM]
   #
@@ -65,7 +64,7 @@ [LibraryClasses.ARM]
   # syscfg MMIO register implementation on ARM.
   # This will not work at actual runtime.
   #
-  ResetSystemLib|ArmPlatformPkg/ArmVExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
+  ResetSystemLib|Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
 
 [BuildOptions]
 !ifdef ARM_BIGLITTLE_TC2
@@ -73,11 +72,11 @@ [BuildOptions]
   *_*_ARM_PP_FLAGS  = -DARM_BIGLITTLE_TC2=1
 !endif
 
-  RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7
+  RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7
 
-  GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7
+  GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a15 -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7
 
-  XCODE:*_*_ARM_PLATFORM_FLAGS = -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7
+  XCODE:*_*_ARM_PLATFORM_FLAGS = -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7
 
 ################################################################################
 #
@@ -209,7 +208,7 @@ [Components.common]
   #
   ArmPlatformPkg/PrePi/PeiMPCore.inf {
     <LibraryClasses>
-      ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
+      ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
   }
 
   #
@@ -248,15 +247,15 @@ [Components.common]
 
   ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
   ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
-  #ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
-  ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
+  #Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
+  Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
   ArmPkg/Drivers/TimerDxe/TimerDxe.inf
   ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
 
   #
   # Platform
   #
-  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf
+  Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
 
   #
   # Filesystems
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf
index cb9a89ef0c7f..d33c3b79f84c 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf
@@ -97,14 +97,14 @@ [FV.FvMain]
   INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
   INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
   INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
-  #INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
-  INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
+  #INF Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
+  INF Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
   INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
 
   #
   # Platform
   #
-  INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf
+  INF Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
 
   #
   # Multimedia Card Interface
@@ -140,7 +140,7 @@ [FV.FvMain]
   #
   INF EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
   INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
-  INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
+  INF Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
 
   # ACPI Support
   INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
@@ -187,7 +187,7 @@ [FV.FvMain]
 
   # Example to add a Device Tree to the Firmware Volume
   #FILE FREEFORM = PCD(gArmVExpressTokenSpaceGuid.PcdFdtVExpressHwA15x2A7x3) {
-  #  SECTION RAW = ArmPlatformPkg/ArmVExpressPkg/Fdts/vexpress-v2p-ca15_a7.dtb
+  #  SECTION RAW = Platform/ARM/VExpressPkg/Fdts/vexpress-v2p-ca15_a7.dtb
   #}
 
 [FV.FVMAIN_COMPACT]
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
index e02a78a9766c..df6951900ed8 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
@@ -41,13 +41,12 @@ [Defines]
 
 [LibraryClasses.common]
   ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
-  ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
+  ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
   ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
 
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+  ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
 !ifdef EDK2_ENABLE_PL111
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
+  LcdPlatformLib|Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
 !endif
 
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
@@ -62,16 +61,16 @@ [LibraryClasses.common]
   DtPlatformDtbLoaderLib|Platform/ARM/VExpressPkg/Library/ArmVExpressDtPlatformDtbLoaderLib/ArmVExpressDtPlatformDtbLoaderLib.inf
 
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
+  ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
 
 [LibraryClasses.common.SEC]
-  ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
+  ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
 
 [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
 
 [BuildOptions]
-  GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/RTSM
+  GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/Platform/ARM/VExpressPkg/Include/Platform/RTSM
 
 
 ################################################################################
@@ -196,7 +195,7 @@ [Components.common]
   # UEFI is placed in RAM by bootloader
   ArmPlatformPkg/PrePi/PeiUniCore.inf {
     <LibraryClasses>
-      ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
+      ArmPlatformLib|Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
   }
 !else
   # UEFI lives in FLASH and copies itself to RAM
@@ -298,7 +297,7 @@ [Components.common]
   #
   # Platform Driver
   #
-  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf
+  Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
 
   #
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf
index 1084eda3d367..0bac8ae91dab 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.fdf
@@ -145,7 +145,7 @@ [FV.FvMain]
   #
   # Platform Driver
   #
-  INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf
+  INF Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf
   INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
 
 !ifdef EDK2_ENABLE_SMSC_91X
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 203a781d9bd5..40e1c868fcb2 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -78,12 +78,12 @@ [LibraryClasses.common]
 
   # Versatile Express Specific Libraries
   PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
-  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
-  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+  ArmPlatformSysConfigLib|Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
+  NorFlashPlatformLib|Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
   ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
 !ifdef EDK2_ENABLE_PL111
   # ARM PL111 Lcd Driver
-  LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
+  LcdPlatformLib|Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
 !endif
   # ARM PL031 RTC Driver
   RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
@@ -472,7 +472,7 @@ [Components.common]
       BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
   }
   EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
-  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
+  Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
 
   # FV Filesystem
   MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
diff --git a/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
new file mode 100644
index 000000000000..3814513c2241
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
@@ -0,0 +1,53 @@
+#/** @file
+# Arm Versatile Express package.
+#
+#  Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = ArmVExpressPkg
+  PACKAGE_GUID                   = 9c0aaed4-74c5-4043-b417-a3223814ce76
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+
+[Guids.common]
+  gArmVExpressTokenSpaceGuid    =  { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }
+
+[PcdsFeatureFlag.common]
+
+[PcdsFixedAtBuild.common]
+  #
+  # MaxMode must be one number higher than the actual max mode,
+  # i.e. for actual maximum mode 2, set the value to 3.
+  #
+  # For a list of mode numbers look in LcdArmVExpress.c
+  #
+  gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode|3|UINT32|0x00000001
+  gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId|1|UINT32|0x00000002
+  gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId|0|UINT32|0x00000003
+
+  #
+  # Device path of block device on which Fastboot will flash partitions
+  #
+  gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|""|VOID*|0x00000004
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c
new file mode 100644
index 000000000000..7827c50d8bbf
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.c
@@ -0,0 +1,90 @@
+/** @file
+
+  Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/ArmShellCmdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/VirtioMmioDeviceLib.h>
+
+#include <VExpressMotherBoard.h>
+
+#define ARM_FVP_BASE_VIRTIO_BLOCK_BASE    0x1c130000
+
+#pragma pack(1)
+typedef struct {
+  VENDOR_DEVICE_PATH                  Vendor;
+  EFI_DEVICE_PATH_PROTOCOL            End;
+} VIRTIO_BLK_DEVICE_PATH;
+#pragma pack()
+
+VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath =
+{
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)( sizeof(VENDOR_DEVICE_PATH) ),
+        (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    EFI_CALLER_ID_GUID,
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      sizeof (EFI_DEVICE_PATH_PROTOCOL),
+      0
+    }
+  }
+};
+
+/**
+ * Generic UEFI Entrypoint for 'ArmFvpDxe' driver
+ * See UEFI specification for the details of the parameters
+ */
+EFI_STATUS
+EFIAPI
+ArmFvpInitialise (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                   Status;
+
+  Status = gBS->InstallProtocolInterface (&ImageHandle,
+                 &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
+                 &mVirtioBlockDevicePath);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Declare the Virtio BlockIo device
+  Status = VirtioMmioInstallDevice (ARM_FVP_BASE_VIRTIO_BLOCK_BASE, ImageHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "ArmFvpDxe: Failed to install Virtio block device\n"));
+  }
+
+  // Install dynamic Shell command to run baremetal binaries.
+  Status = ShellDynCmdRunAxfInstall (ImageHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "ArmFvpDxe: Failed to install ShellDynCmdRunAxf\n"));
+  }
+
+  return Status;
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf
new file mode 100644
index 000000000000..1d208261201b
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmFvpDxe.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+#  Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = ArmFvpDxe
+  FILE_GUID                      = 405b2307-6839-4d52-aeb9-bece64252800
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ArmFvpInitialise
+
+[Sources.common]
+  ArmFvpDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  OvmfPkg/OvmfPkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  ArmShellCmdRunAxfLib
+  BaseMemoryLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  VirtioMmioDeviceLib
+
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c
new file mode 100644
index 000000000000..19efa3c23dea
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.c
@@ -0,0 +1,38 @@
+/** @file
+
+  Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/ArmShellCmdLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ * Generic UEFI Entrypoint for 'ArmHwDxe' driver
+ * See UEFI specification for the details of the parameters
+ */
+EFI_STATUS
+EFIAPI
+ArmHwInitialise (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  // Install dynamic Shell command to run baremetal binaries.
+  Status = ShellDynCmdRunAxfInstall (ImageHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "ArmHwDxe: Failed to install ShellDynCmdRunAxf\n"));
+  }
+
+  return Status;
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
new file mode 100644
index 000000000000..1ecdbb0b231e
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
@@ -0,0 +1,37 @@
+#/** @file
+#
+#  Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = ArmHwDxe
+  FILE_GUID                      = fe61bb5f-1b67-4c24-b346-73db42e873e5
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ArmHwInitialise
+
+[Sources.common]
+  ArmHwDxe.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmShellCmdRunAxfLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c
new file mode 100644
index 000000000000..a01bf3c671ad
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c
@@ -0,0 +1,519 @@
+/** @file
+
+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+/*
+  Implementation of the Android Fastboot Platform protocol, to be used by the
+  Fastboot UEFI application, for ARM Versatile Express platforms.
+*/
+
+#include <Protocol/AndroidFastbootPlatform.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define FLASH_DEVICE_PATH_SIZE(DevPath) ( GetDevicePathSize (DevPath) - \
+                                            sizeof (EFI_DEVICE_PATH_PROTOCOL))
+
+#define PARTITION_NAME_MAX_LENGTH 72/2
+
+#define IS_ALPHA(Char) (((Char) <= L'z' && (Char) >= L'a') || \
+                        ((Char) <= L'Z' && (Char) >= L'Z'))
+
+typedef struct _FASTBOOT_PARTITION_LIST {
+  LIST_ENTRY  Link;
+  CHAR16      PartitionName[PARTITION_NAME_MAX_LENGTH];
+  EFI_HANDLE  PartitionHandle;
+} FASTBOOT_PARTITION_LIST;
+
+STATIC LIST_ENTRY mPartitionListHead;
+
+/*
+  Helper to free the partition list
+*/
+STATIC
+VOID
+FreePartitionList (
+  VOID
+  )
+{
+  FASTBOOT_PARTITION_LIST *Entry;
+  FASTBOOT_PARTITION_LIST *NextEntry;
+
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+
+    RemoveEntryList (&Entry->Link);
+    FreePool (Entry);
+
+    Entry = NextEntry;
+  }
+}
+/*
+  Read the PartitionName fields from the GPT partition entries, putting them
+  into an allocated array that should later be freed.
+*/
+STATIC
+EFI_STATUS
+ReadPartitionEntries (
+  IN  EFI_BLOCK_IO_PROTOCOL *BlockIo,
+  OUT EFI_PARTITION_ENTRY  **PartitionEntries
+  )
+{
+  UINTN                       EntrySize;
+  UINTN                       NumEntries;
+  UINTN                       BufferSize;
+  UINT32                      MediaId;
+  EFI_PARTITION_TABLE_HEADER *GptHeader;
+  EFI_STATUS                  Status;
+
+  MediaId = BlockIo->Media->MediaId;
+
+  //
+  // Read size of Partition entry and number of entries from GPT header
+  //
+
+  GptHeader = AllocatePool (BlockIo->Media->BlockSize);
+  if (GptHeader == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = BlockIo->ReadBlocks (BlockIo, MediaId, 1, BlockIo->Media->BlockSize, (VOID *) GptHeader);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Check there is a GPT on the media
+  if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||
+      GptHeader->MyLBA != 1) {
+    DEBUG ((EFI_D_ERROR,
+      "Fastboot platform: No GPT on flash. "
+      "Fastboot on Versatile Express does not support MBR.\n"
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  EntrySize = GptHeader->SizeOfPartitionEntry;
+  NumEntries = GptHeader->NumberOfPartitionEntries;
+
+  FreePool (GptHeader);
+
+  ASSERT (EntrySize != 0);
+  ASSERT (NumEntries != 0);
+
+  BufferSize = ALIGN_VALUE (EntrySize * NumEntries, BlockIo->Media->BlockSize);
+  *PartitionEntries = AllocatePool (BufferSize);
+  if (PartitionEntries == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = BlockIo->ReadBlocks (BlockIo, MediaId, 2, BufferSize, (VOID *) *PartitionEntries);
+  if (EFI_ERROR (Status)) {
+    FreePool (PartitionEntries);
+    return Status;
+  }
+
+  return Status;
+}
+
+
+/*
+  Do any initialisation that needs to be done in order to be able to respond to
+  commands.
+
+  @retval EFI_SUCCESS   Initialised successfully.
+  @retval !EFI_SUCCESS  Error in initialisation.
+*/
+STATIC
+EFI_STATUS
+ArmFastbootPlatformInit (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL           *NextNode;
+  HARDDRIVE_DEVICE_PATH              *PartitionNode;
+  UINTN                               NumHandles;
+  EFI_HANDLE                         *AllHandles;
+  UINTN                               LoopIndex;
+  EFI_HANDLE                          FlashHandle;
+  EFI_BLOCK_IO_PROTOCOL              *FlashBlockIo;
+  EFI_PARTITION_ENTRY                *PartitionEntries;
+  FASTBOOT_PARTITION_LIST            *Entry;
+
+  InitializeListHead (&mPartitionListHead);
+
+  //
+  // Get EFI_HANDLES for all the partitions on the block devices pointed to by
+  // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
+  // We will use these labels as the key in ArmFastbootPlatformFlashPartition.
+  // There's no way to find all of a device's children, so we get every handle
+  // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
+  // that don't represent partitions on the flash device.
+  //
+
+  FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
+
+  //
+  // Open the Disk IO protocol on the flash device - this will be used to read
+  // partition names out of the GPT entries
+  //
+  // Create another device path pointer because LocateDevicePath will modify it.
+  FlashDevicePathDup = FlashDevicePath;
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
+    // Failing to locate partitions should not prevent to do other Android FastBoot actions
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->OpenProtocol (
+                  FlashHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &FlashBlockIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
+    return EFI_DEVICE_ERROR;
+  }
+
+  // Read the GPT partition entry array into memory so we can get the partition names
+  Status = ReadPartitionEntries (FlashBlockIo, &PartitionEntries);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
+    // Failing to locate partitions should not prevent to do other Android FastBoot actions
+    return EFI_SUCCESS;
+  }
+
+  // Get every Block IO protocol instance installed in the system
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiBlockIoProtocolGuid,
+                  NULL,
+                  &NumHandles,
+                  &AllHandles
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  // Filter out handles that aren't children of the flash device
+  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
+    // Get the device path for the handle
+    Status = gBS->OpenProtocol (
+                    AllHandles[LoopIndex],
+                    &gEfiDevicePathProtocolGuid,
+                    (VOID **) &DevicePath,
+                    gImageHandle,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    // Check if it is a sub-device of the flash device
+    if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) {
+      // Device path starts with path of flash device. Check it isn't the flash
+      // device itself.
+      NextNode = NextDevicePathNode (DevicePath);
+      if (IsDevicePathEndType (NextNode)) {
+        continue;
+      }
+
+      // Assert that this device path node represents a partition.
+      ASSERT (NextNode->Type == MEDIA_DEVICE_PATH &&
+              NextNode->SubType == MEDIA_HARDDRIVE_DP);
+
+      PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode;
+
+      // Assert that the partition type is GPT. ReadPartitionEntries checks for
+      // presence of a GPT, so we should never find MBR partitions.
+      // ("MBRType" is a misnomer - this field is actually called "Partition
+      //  Format")
+      ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER);
+
+      // The firmware may install a handle for "partition 0", representing the
+      // whole device. Ignore it.
+      if (PartitionNode->PartitionNumber == 0) {
+        continue;
+      }
+
+      //
+      // Add the partition handle to the list
+      //
+
+      // Create entry
+      Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
+      if (Entry == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        FreePartitionList ();
+        goto Exit;
+      }
+
+      // Copy handle and partition name
+      Entry->PartitionHandle = AllHandles[LoopIndex];
+      CopyMem (
+        Entry->PartitionName,
+        PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1.
+        PARTITION_NAME_MAX_LENGTH
+        );
+      InsertTailList (&mPartitionListHead, &Entry->Link);
+
+      // Print a debug message if the partition label is empty or looks like
+      // garbage.
+      if (!IS_ALPHA (Entry->PartitionName[0])) {
+        DEBUG ((EFI_D_ERROR,
+          "Warning: Partition %d doesn't seem to have a GPT partition label. "
+          "You won't be able to flash it with Fastboot.\n",
+          PartitionNode->PartitionNumber
+          ));
+      }
+    }
+  }
+
+Exit:
+  FreePool (PartitionEntries);
+  FreePool (FlashDevicePath);
+  FreePool (AllHandles);
+  return Status;
+
+}
+
+/*
+  To be called when Fastboot is finished and we aren't rebooting or booting an
+  image. Undo initialisation, free resrouces.
+*/
+STATIC
+VOID
+ArmFastbootPlatformUnInit (
+  VOID
+  )
+{
+  FreePartitionList ();
+}
+
+/*
+  Flash the partition named (according to a platform-specific scheme)
+  PartitionName, with the image pointed to by Buffer, whose size is BufferSize.
+
+  @param[in] PartitionName  Null-terminated name of partition to write.
+  @param[in] BufferSize     Size of Buffer in byets.
+  @param[in] Buffer         Data to write to partition.
+
+  @retval EFI_NOT_FOUND     No such partition.
+  @retval EFI_DEVICE_ERROR  Flashing failed.
+*/
+STATIC
+EFI_STATUS
+ArmFastbootPlatformFlashPartition (
+  IN CHAR8  *PartitionName,
+  IN UINTN   Size,
+  IN VOID   *Image
+  )
+{
+  EFI_STATUS               Status;
+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;
+  EFI_DISK_IO_PROTOCOL    *DiskIo;
+  UINT32                   MediaId;
+  UINTN                    PartitionSize;
+  FASTBOOT_PARTITION_LIST *Entry;
+  CHAR16                   PartitionNameUnicode[60];
+  BOOLEAN                  PartitionFound;
+
+  AsciiStrToUnicodeStrS (PartitionName, PartitionNameUnicode,
+    ARRAY_SIZE (PartitionNameUnicode));
+
+  PartitionFound = FALSE;
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    // Search the partition list for the partition named by PartitionName
+    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+      PartitionFound = TRUE;
+      break;
+    }
+
+   Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+  }
+  if (!PartitionFound) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = gBS->OpenProtocol (
+                  Entry->PartitionHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &BlockIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status));
+    return EFI_NOT_FOUND;
+  }
+
+  // Check image will fit on device
+  PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize;
+  if (PartitionSize < Size) {
+    DEBUG ((EFI_D_ERROR, "Partition not big enough.\n"));
+    DEBUG ((EFI_D_ERROR, "Partition Size:\t%d\nImage Size:\t%d\n", PartitionSize, Size));
+
+    return EFI_VOLUME_FULL;
+  }
+
+  MediaId = BlockIo->Media->MediaId;
+
+  Status = gBS->OpenProtocol (
+                  Entry->PartitionHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  BlockIo->FlushBlocks(BlockIo);
+
+  return Status;
+}
+
+/*
+  Erase the partition named PartitionName.
+
+  @param[in] PartitionName  Null-terminated name of partition to erase.
+
+  @retval EFI_NOT_FOUND     No such partition.
+  @retval EFI_DEVICE_ERROR  Erasing failed.
+*/
+STATIC
+EFI_STATUS
+ArmFastbootPlatformErasePartition (
+  IN CHAR8 *Partition
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/*
+  If the variable referred to by Name exists, copy it (as a null-terminated
+  string) into Value. If it doesn't exist, put the Empty string in Value.
+
+  Variable names and values may not be larger than 60 bytes, excluding the
+  terminal null character. This is a limitation of the Fastboot protocol.
+
+  The Fastboot application will handle platform-nonspecific variables
+  (Currently "version" is the only one of these.)
+
+  @param[in]  Name   Null-terminated name of Fastboot variable to retrieve.
+  @param[out] Value  Caller-allocated buffer for null-terminated value of
+                     variable.
+
+  @retval EFI_SUCCESS       The variable was retrieved, or it doesn't exist.
+  @retval EFI_DEVICE_ERROR  There was an error looking up the variable. This
+                            does _not_ include the variable not existing.
+*/
+STATIC
+EFI_STATUS
+ArmFastbootPlatformGetVar (
+  IN  CHAR8   *Name,
+  OUT CHAR8   *Value
+  )
+{
+  if (AsciiStrCmp (Name, "product")) {
+    AsciiStrCpyS (Value, 61, FixedPcdGetPtr (PcdFirmwareVendor));
+  } else {
+    *Value = '\0';
+  }
+  return EFI_SUCCESS;
+}
+
+/*
+  React to an OEM-specific command.
+
+  Future versions of this function might want to allow the platform to do some
+  extra communication with the host. A way to do this would be to add a function
+  to the FASTBOOT_TRANSPORT_PROTOCOL that allows the implementation of
+  DoOemCommand to replace the ReceiveEvent with its own, and to restore the old
+  one when it's finished.
+
+  However at the moment although the specification allows it, the AOSP fastboot
+  host application doesn't handle receiving any data from the client, and it
+  doesn't support a data phase for OEM commands.
+
+  @param[in] Command    Null-terminated command string.
+
+  @retval EFI_SUCCESS       The command executed successfully.
+  @retval EFI_NOT_FOUND     The command wasn't recognised.
+  @retval EFI_DEVICE_ERROR  There was an error executing the command.
+*/
+STATIC
+EFI_STATUS
+ArmFastbootPlatformOemCommand (
+  IN  CHAR8   *Command
+  )
+{
+  CHAR16 CommandUnicode[65];
+
+  AsciiStrToUnicodeStrS (Command, CommandUnicode, ARRAY_SIZE (CommandUnicode));
+
+  if (AsciiStrCmp (Command, "Demonstrate") == 0) {
+    DEBUG ((EFI_D_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
+    return EFI_SUCCESS;
+  } else {
+    DEBUG ((EFI_D_ERROR,
+      "VExpress: Unrecognised Fastboot OEM command: %s\n",
+      CommandUnicode
+      ));
+    return EFI_NOT_FOUND;
+  }
+}
+
+STATIC FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {
+  ArmFastbootPlatformInit,
+  ArmFastbootPlatformUnInit,
+  ArmFastbootPlatformFlashPartition,
+  ArmFastbootPlatformErasePartition,
+  ArmFastbootPlatformGetVar,
+  ArmFastbootPlatformOemCommand
+};
+
+EFI_STATUS
+EFIAPI
+ArmAndroidFastbootPlatformEntryPoint (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  return gBS->InstallProtocolInterface (
+                &ImageHandle,
+                &gAndroidFastbootPlatformProtocolGuid,
+                EFI_NATIVE_INTERFACE,
+                &mPlatformProtocol
+                );
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
new file mode 100644
index 000000000000..07c5e1e230e9
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
@@ -0,0 +1,51 @@
+#/** @file
+#
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmVExpressFastBootDxe
+  FILE_GUID                      = 4004e454-89a0-11e3-89aa-97ef9d942abc
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ArmAndroidFastbootPlatformEntryPoint
+
+[Sources.common]
+  ArmVExpressFastBoot.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gAndroidFastbootPlatformProtocolGuid
+  gEfiBlockIoProtocolGuid
+  gEfiDiskIoProtocolGuid
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPkg/ArmPkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[Pcd]
+  gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c
new file mode 100644
index 000000000000..2bfe2c0fe2dc
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcd.c
@@ -0,0 +1,133 @@
+/** @file  Lcd.c
+
+  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/LcdPlatformLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+#include <Drivers/HdLcd.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+/**********************************************************************
+ *
+ *  This file contains all the bits of the Lcd that are
+ *  platform independent.
+ *
+ **********************************************************************/
+
+EFI_STATUS
+LcdInitialize (
+  IN EFI_PHYSICAL_ADDRESS   VramBaseAddress
+  )
+{
+  // Disable the controller
+  MmioWrite32(HDLCD_REG_COMMAND, HDLCD_DISABLE);
+
+  // Disable all interrupts
+  MmioWrite32(HDLCD_REG_INT_MASK, 0);
+
+  // Define start of the VRAM. This never changes for any graphics mode
+  MmioWrite32(HDLCD_REG_FB_BASE, (UINT32) VramBaseAddress);
+
+  // Setup various registers that never change
+  MmioWrite32(HDLCD_REG_BUS_OPTIONS,  (4 << 8) | HDLCD_BURST_8);
+  MmioWrite32(HDLCD_REG_POLARITIES,   HDLCD_PXCLK_LOW | HDLCD_DATA_HIGH | HDLCD_DATEN_HIGH | HDLCD_HSYNC_LOW | HDLCD_VSYNC_HIGH);
+  MmioWrite32(HDLCD_REG_PIXEL_FORMAT, HDLCD_LITTLE_ENDIAN | HDLCD_4BYTES_PER_PIXEL);
+  MmioWrite32(HDLCD_REG_RED_SELECT,   (0 << 16 | 8 << 8 |  0));
+  MmioWrite32(HDLCD_REG_GREEN_SELECT, (0 << 16 | 8 << 8 |  8));
+  MmioWrite32(HDLCD_REG_BLUE_SELECT,  (0 << 16 | 8 << 8 | 16));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdSetMode (
+  IN UINT32  ModeNumber
+  )
+{
+  EFI_STATUS        Status;
+  UINT32            HRes;
+  UINT32            HSync;
+  UINT32            HBackPorch;
+  UINT32            HFrontPorch;
+  UINT32            VRes;
+  UINT32            VSync;
+  UINT32            VBackPorch;
+  UINT32            VFrontPorch;
+  UINT32            BytesPerPixel;
+  LCD_BPP           LcdBpp;
+
+
+  // Set the video mode timings and other relevant information
+  Status = LcdPlatformGetTimings (ModeNumber,
+                                  &HRes,&HSync,&HBackPorch,&HFrontPorch,
+                                  &VRes,&VSync,&VBackPorch,&VFrontPorch);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR( Status )) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = LcdPlatformGetBpp (ModeNumber,&LcdBpp);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR( Status )) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  BytesPerPixel = GetBytesPerPixel(LcdBpp);
+
+  // Disable the controller
+  MmioWrite32(HDLCD_REG_COMMAND, HDLCD_DISABLE);
+
+  // Update the frame buffer information with the new settings
+  MmioWrite32(HDLCD_REG_FB_LINE_LENGTH, HRes * BytesPerPixel);
+  MmioWrite32(HDLCD_REG_FB_LINE_PITCH,  HRes * BytesPerPixel);
+  MmioWrite32(HDLCD_REG_FB_LINE_COUNT,  VRes - 1);
+
+  // Set the vertical timing information
+  MmioWrite32(HDLCD_REG_V_SYNC,         VSync);
+  MmioWrite32(HDLCD_REG_V_BACK_PORCH,   VBackPorch);
+  MmioWrite32(HDLCD_REG_V_DATA,         VRes - 1);
+  MmioWrite32(HDLCD_REG_V_FRONT_PORCH,  VFrontPorch);
+
+  // Set the horizontal timing information
+  MmioWrite32(HDLCD_REG_H_SYNC,         HSync);
+  MmioWrite32(HDLCD_REG_H_BACK_PORCH,   HBackPorch);
+  MmioWrite32(HDLCD_REG_H_DATA,         HRes - 1);
+  MmioWrite32(HDLCD_REG_H_FRONT_PORCH,  HFrontPorch);
+
+  // Enable the controller
+  MmioWrite32(HDLCD_REG_COMMAND, HDLCD_ENABLE);
+
+  return EFI_SUCCESS;
+}
+
+VOID
+LcdShutdown (
+  VOID
+  )
+{
+  // Disable the controller
+  MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
+}
+
+EFI_STATUS
+LcdIdentify (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
new file mode 100644
index 000000000000..34e12987038e
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
@@ -0,0 +1,63 @@
+#/** @file
+#
+#  Component description file for HDLCD module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = HdLcdGraphicsDxe
+  FILE_GUID                      = ce660500-824d-11e0-ac72-0002a5d5c51b
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = LcdGraphicsOutputDxeInitialize
+
+[Sources.common]
+  LcdGraphicsOutputDxe.c
+  LcdGraphicsOutputBlt.c
+  HdLcd.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  UefiLib
+  BaseLib
+  DebugLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  IoLib
+  BaseMemoryLib
+  LcdPlatformLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiGraphicsOutputProtocolGuid                # Produced
+  gEfiEdidDiscoveredProtocolGuid                # Produced
+  gEfiEdidActiveProtocolGuid                    # Produced
+  gEfiEdidOverrideProtocolGuid                  # Produced
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdArmHdLcdBase
+
+[FeaturePcd]
+  gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices
+
+[Depex]
+  gEfiCpuArchProtocolGuid
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
new file mode 100644
index 000000000000..77f93cbb675e
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
@@ -0,0 +1,882 @@
+/** @file
+
+ Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+extern BOOLEAN mDisplayInitialized;
+
+//
+// Function Definitions
+//
+
+STATIC
+EFI_STATUS
+VideoCopyNoHorizontalOverlap (
+  IN UINTN          BitsPerPixel,
+  IN volatile VOID  *FrameBufferBase,
+  IN UINT32         HorizontalResolution,
+  IN UINTN          SourceX,
+  IN UINTN          SourceY,
+  IN UINTN          DestinationX,
+  IN UINTN          DestinationY,
+  IN UINTN          Width,
+  IN UINTN          Height
+)
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+  UINTN         SourceLine;
+  UINTN         DestinationLine;
+  UINTN         WidthInBytes;
+  UINTN         LineCount;
+  INTN          Step;
+  VOID          *SourceAddr;
+  VOID          *DestinationAddr;
+
+  if( DestinationY <= SourceY ) {
+    // scrolling up (or horizontally but without overlap)
+    SourceLine       = SourceY;
+    DestinationLine  = DestinationY;
+    Step             = 1;
+  } else {
+    // scrolling down
+    SourceLine       = SourceY + Height;
+    DestinationLine  = DestinationY + Height;
+    Step             = -1;
+  }
+
+  switch (BitsPerPixel) {
+
+  case LCD_BITS_PER_PIXEL_24:
+
+    WidthInBytes = Width * 4;
+
+    for( LineCount = 0; LineCount < Height; LineCount++ ) {
+      // Update the start addresses of source & destination using 32bit pointer arithmetic
+      SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );
+      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
+
+      // Copy the entire line Y from video ram to the temp buffer
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
+
+      // Update the line numbers
+      SourceLine      += Step;
+      DestinationLine += Step;
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_555:
+  case LCD_BITS_PER_PIXEL_16_565:
+  case LCD_BITS_PER_PIXEL_12_444:
+
+    WidthInBytes = Width * 2;
+
+    for( LineCount = 0; LineCount < Height; LineCount++ ) {
+      // Update the start addresses of source & destination using 16bit pointer arithmetic
+      SourceAddr      = (VOID *)((UINT16 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );
+      DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
+
+      // Copy the entire line Y from video ram to the temp buffer
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
+
+      // Update the line numbers
+      SourceLine      += Step;
+      DestinationLine += Step;
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_8:
+  case LCD_BITS_PER_PIXEL_4:
+  case LCD_BITS_PER_PIXEL_2:
+  case LCD_BITS_PER_PIXEL_1:
+  default:
+    // Can't handle this case
+    DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT;
+    // break;
+
+  }
+
+  EXIT:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+VideoCopyHorizontalOverlap (
+  IN UINTN          BitsPerPixel,
+  IN volatile VOID  *FrameBufferBase,
+  UINT32            HorizontalResolution,
+  IN UINTN          SourceX,
+  IN UINTN          SourceY,
+  IN UINTN          DestinationX,
+  IN UINTN          DestinationY,
+  IN UINTN          Width,
+  IN UINTN          Height
+)
+{
+  EFI_STATUS      Status = EFI_SUCCESS;
+
+  UINT32 *PixelBuffer32bit;
+  UINT32 *SourcePixel32bit;
+  UINT32 *DestinationPixel32bit;
+
+  UINT16 *PixelBuffer16bit;
+  UINT16 *SourcePixel16bit;
+  UINT16 *DestinationPixel16bit;
+
+  UINT32          SourcePixelY;
+  UINT32          DestinationPixelY;
+  UINTN           SizeIn32Bits;
+  UINTN           SizeIn16Bits;
+
+  switch (BitsPerPixel) {
+
+  case LCD_BITS_PER_PIXEL_24:
+    // Allocate a temporary buffer
+
+    PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32));
+
+    if (PixelBuffer32bit == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto EXIT;
+    }
+
+    SizeIn32Bits = Width * 4;
+
+    // Copy from the video ram (source region) to a temp buffer
+    for (SourcePixelY = SourceY, DestinationPixel32bit = PixelBuffer32bit;
+         SourcePixelY < SourceY + Height;
+         SourcePixelY++, DestinationPixel32bit += Width)
+    {
+      // Update the start address of line Y (source)
+      SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
+
+      // Copy the entire line Y from video ram to the temp buffer
+      CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
+    }
+
+    // Copy from the temp buffer to the video ram (destination region)
+    for (DestinationPixelY = DestinationY, SourcePixel32bit = PixelBuffer32bit;
+         DestinationPixelY < DestinationY + Height;
+         DestinationPixelY++, SourcePixel32bit += Width)
+    {
+      // Update the start address of line Y (target)
+      DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX;
+
+      // Copy the entire line Y from the temp buffer to video ram
+      CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
+    }
+
+    // Free up the allocated memory
+    FreePool((VOID *) PixelBuffer32bit);
+
+    break;
+
+
+  case LCD_BITS_PER_PIXEL_16_555:
+  case LCD_BITS_PER_PIXEL_16_565:
+  case LCD_BITS_PER_PIXEL_12_444:
+    // Allocate a temporary buffer
+    PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16));
+
+    if (PixelBuffer16bit == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto EXIT;
+    }
+
+    // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
+
+    SizeIn16Bits = Width * 2;
+
+    for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;
+         SourcePixelY < SourceY + Height;
+         SourcePixelY++, DestinationPixel16bit += Width)
+    {
+      // Calculate the source address:
+      SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
+
+      // Copy the entire line Y from Video to the temp buffer
+      CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
+    }
+
+    // Copy from the temp buffer into the destination area of the Video Memory
+
+    for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;
+         DestinationPixelY < DestinationY + Height;
+         DestinationPixelY++, SourcePixel16bit += Width)
+    {
+      // Calculate the target address:
+      DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);
+
+      // Copy the entire line Y from the temp buffer to Video
+      CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
+    }
+
+    // Free the allocated memory
+    FreePool((VOID *) PixelBuffer16bit);
+
+    break;
+
+
+  case LCD_BITS_PER_PIXEL_8:
+  case LCD_BITS_PER_PIXEL_4:
+  case LCD_BITS_PER_PIXEL_2:
+  case LCD_BITS_PER_PIXEL_1:
+  default:
+    // Can't handle this case
+    DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT;
+    // break;
+
+  }
+
+EXIT:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoFill (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *EfiSourcePixel,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_PIXEL_BITMASK*  PixelInformation;
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  LCD_BPP            BitsPerPixel;
+  VOID            *FrameBufferBase;
+  VOID            *DestinationAddr;
+  UINT16          *DestinationPixel16bit;
+  UINT16          Pixel16bit;
+  UINT32          DestinationPixelX;
+  UINT32          DestinationLine;
+  UINTN           WidthInBytes;
+
+  Status           = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
+
+  switch (BitsPerPixel) {
+  case LCD_BITS_PER_PIXEL_24:
+    WidthInBytes = Width * 4;
+
+    // Copy the SourcePixel into every pixel inside the target rectangle
+    for (DestinationLine = DestinationY;
+         DestinationLine < DestinationY + Height;
+         DestinationLine++)
+    {
+      // Calculate the target address using 32bit pointer arithmetic:
+      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationX);
+
+      // Fill the entire line
+      SetMem32 (DestinationAddr, WidthInBytes, *((UINT32 *)EfiSourcePixel));
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_555:
+    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
+    Pixel16bit = (UINT16) (
+        ( (EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask      )
+      | ( (EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask    )
+      | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+//      | ( 0                           & PixelInformation->ReservedMask )
+     );
+
+    // Copy the SourcePixel into every pixel inside the target rectangle
+    for (DestinationLine = DestinationY;
+         DestinationLine < DestinationY + Height;
+         DestinationLine++)
+    {
+      for (DestinationPixelX = DestinationX;
+           DestinationPixelX < DestinationX + Width;
+           DestinationPixelX++)
+      {
+        // Calculate the target address:
+        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
+
+        // Copy the pixel into the new target
+        *DestinationPixel16bit = Pixel16bit;
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_565:
+    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
+    Pixel16bit = (UINT16) (
+        ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
+      | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
+      | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+     );
+
+    // Copy the SourcePixel into every pixel inside the target rectangle
+    for (DestinationLine = DestinationY;
+         DestinationLine < DestinationY + Height;
+         DestinationLine++)
+    {
+      for (DestinationPixelX = DestinationX;
+           DestinationPixelX < DestinationX + Width;
+           DestinationPixelX++)
+      {
+        // Calculate the target address:
+        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;
+
+        // Copy the pixel into the new target
+        *DestinationPixel16bit = Pixel16bit;
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_12_444:
+    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
+    Pixel16bit = (UINT16) (
+        ( (EfiSourcePixel->Red      >> 4) & PixelInformation->RedMask      )
+      | ( (EfiSourcePixel->Green        ) & PixelInformation->GreenMask    )
+      | ( (EfiSourcePixel->Blue     << 4) & PixelInformation->BlueMask     )
+     );
+
+    // Copy the SourcePixel into every pixel inside the target rectangle
+    for (DestinationLine = DestinationY;
+         DestinationLine < DestinationY + Height;
+         DestinationLine++)
+    {
+      for (DestinationPixelX = DestinationX;
+           DestinationPixelX < DestinationX + Width;
+           DestinationPixelX++)
+      {
+        // Calculate the target address:
+        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;
+
+        // Copy the pixel into the new target
+        *DestinationPixel16bit = Pixel16bit;
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_8:
+  case LCD_BITS_PER_PIXEL_4:
+  case LCD_BITS_PER_PIXEL_2:
+  case LCD_BITS_PER_PIXEL_1:
+  default:
+    // Can't handle this case
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
+    Status = EFI_INVALID_PARAMETER;
+    break;
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoToBltBuffer (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  LCD_BPP            BitsPerPixel;
+  EFI_PIXEL_BITMASK  *PixelInformation;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;
+  VOID   *FrameBufferBase;
+  VOID            *SourceAddr;
+  VOID            *DestinationAddr;
+  UINT16 *SourcePixel16bit;
+  UINT16          Pixel16bit;
+  UINT32          SourcePixelX;
+  UINT32          SourceLine;
+  UINT32          DestinationPixelX;
+  UINT32          DestinationLine;
+  UINT32          BltBufferHorizontalResolution;
+  UINTN           WidthInBytes;
+
+  Status = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    // Delta is not zero and it is different from the width.
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+  } else {
+    BltBufferHorizontalResolution = Width;
+  }
+
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
+
+  switch (BitsPerPixel) {
+  case LCD_BITS_PER_PIXEL_24:
+    WidthInBytes = Width * 4;
+
+    // Access each line inside the Video Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+         SourceLine < SourceY + Height;
+         SourceLine++, DestinationLine++)
+    {
+      // Calculate the source and target addresses using 32bit pointer arithmetic:
+      SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution          + SourceX     );
+      DestinationAddr = (VOID *)((UINT32 *)BltBuffer       + DestinationLine * BltBufferHorizontalResolution + DestinationX);
+
+      // Copy the entire line
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_555:
+    // Access each pixel inside the Video Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+         SourceLine < SourceY + Height;
+         SourceLine++, DestinationLine++)
+    {
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+           SourcePixelX < SourceX + Width;
+           SourcePixelX++, DestinationPixelX++)
+      {
+        // Calculate the source and target addresses:
+        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
+        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
+
+        // Snapshot the pixel from the video buffer once, to speed up the operation.
+        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
+        Pixel16bit = *SourcePixel16bit;
+
+        // Copy the pixel into the new target
+        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >>  7 );
+        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >>  2);
+        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) <<  3 );
+        // EfiDestinationPixel->Reserved = (UINT8) 0;
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_565:
+    // Access each pixel inside the Video Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+         SourceLine < SourceY + Height;
+         SourceLine++, DestinationLine++)
+    {
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+           SourcePixelX < SourceX + Width;
+           SourcePixelX++, DestinationPixelX++)
+      {
+        // Calculate the source and target addresses:
+        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
+        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
+
+        // Snapshot the pixel from the video buffer once, to speed up the operation.
+        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
+        Pixel16bit = *SourcePixel16bit;
+
+        // Copy the pixel into the new target
+        // There is no info for the Reserved byte, so we set it to zero
+        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >> 8 );
+        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >> 3);
+        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) << 3 );
+        // EfiDestinationPixel->Reserved = (UINT8) 0;
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_12_444:
+    // Access each pixel inside the Video Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+         SourceLine < SourceY + Height;
+         SourceLine++, DestinationLine++)
+    {
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+           SourcePixelX < SourceX + Width;
+           SourcePixelX++, DestinationPixelX++)
+      {
+        // Calculate the source and target addresses:
+        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
+        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
+
+        // Snapshot the pixel from the video buffer once, to speed up the operation.
+        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
+        Pixel16bit = *SourcePixel16bit;
+
+        // Copy the pixel into the new target
+        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >> 4 );
+        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   )     );
+        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) << 4 );
+        // EfiDestinationPixel->Reserved = (UINT8) 0;
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_8:
+  case LCD_BITS_PER_PIXEL_4:
+  case LCD_BITS_PER_PIXEL_2:
+  case LCD_BITS_PER_PIXEL_1:
+  default:
+    // Can't handle this case
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
+    Status = EFI_INVALID_PARAMETER;
+    break;
+  }
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltBufferToVideo (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  LCD_BPP            BitsPerPixel;
+  EFI_PIXEL_BITMASK  *PixelInformation;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;
+  VOID   *FrameBufferBase;
+  VOID            *SourceAddr;
+  VOID            *DestinationAddr;
+  UINT16 *DestinationPixel16bit;
+  UINT32          SourcePixelX;
+  UINT32          SourceLine;
+  UINT32          DestinationPixelX;
+  UINT32          DestinationLine;
+  UINT32          BltBufferHorizontalResolution;
+  UINTN           WidthInBytes;
+
+  Status = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    // Delta is not zero and it is different from the width.
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+  } else {
+    BltBufferHorizontalResolution = Width;
+  }
+
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
+
+  switch (BitsPerPixel) {
+  case LCD_BITS_PER_PIXEL_24:
+    WidthInBytes = Width * 4;
+
+    // Access each pixel inside the BltBuffer Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+       SourceLine < SourceY + Height;
+       SourceLine++, DestinationLine++)
+    {
+      // Calculate the source and target addresses using 32bit pointer arithmetic:
+      SourceAddr      = (VOID *)((UINT32 *)BltBuffer       + SourceLine      * BltBufferHorizontalResolution + SourceX     );
+      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution          + DestinationX);
+
+      // Copy the entire row Y
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_555:
+    // Access each pixel inside the BltBuffer Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+       SourceLine < SourceY + Height;
+       SourceLine++, DestinationLine++) {
+
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+           SourcePixelX < SourceX + Width;
+           SourcePixelX++, DestinationPixelX++)
+      {
+        // Calculate the source and target addresses:
+        EfiSourcePixel  = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
+        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
+
+        // Copy the pixel into the new target
+        // Only the most significant bits will be copied across:
+        // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
+        *DestinationPixel16bit = (UINT16) (
+              ( (EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask      )
+            | ( (EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask    )
+            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+      //            | ( 0                                & PixelInformation->ReservedMask )
+            );
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_16_565:
+    // Access each pixel inside the BltBuffer Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+         SourceLine < SourceY + Height;
+         SourceLine++, DestinationLine++) {
+
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+           SourcePixelX < SourceX + Width;
+           SourcePixelX++, DestinationPixelX++)
+      {
+        // Calculate the source and target addresses:
+        EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
+        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
+
+        // Copy the pixel into the new target
+        // Only the most significant bits will be copied across:
+        // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2  least significant bits
+        // There is no room for the Reserved byte so we ignore that completely
+        *DestinationPixel16bit = (UINT16) (
+              ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
+            | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
+            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+           );
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_12_444:
+    // Access each pixel inside the BltBuffer Memory
+    for (SourceLine = SourceY, DestinationLine = DestinationY;
+         SourceLine < SourceY + Height;
+         SourceLine++, DestinationLine++) {
+
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+           SourcePixelX < SourceX + Width;
+           SourcePixelX++, DestinationPixelX++)
+      {
+        // Calculate the source and target addresses:
+        EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
+        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
+
+        // Copy the pixel into the new target
+        // Only the most significant bits will be copied across:
+        // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
+        *DestinationPixel16bit = (UINT16) (
+              ( (EfiSourcePixel->Red      << 4) & PixelInformation->RedMask      )
+            | ( (EfiSourcePixel->Green        ) & PixelInformation->GreenMask    )
+            | ( (EfiSourcePixel->Blue     >> 4) & PixelInformation->BlueMask     )
+  //            | ( 0                               & PixelInformation->ReservedMask )
+           );
+      }
+    }
+    break;
+
+  case LCD_BITS_PER_PIXEL_8:
+  case LCD_BITS_PER_PIXEL_4:
+  case LCD_BITS_PER_PIXEL_2:
+  case LCD_BITS_PER_PIXEL_1:
+  default:
+    // Can't handle this case
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
+    Status = EFI_INVALID_PARAMETER;
+    break;
+  }
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoToVideo (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  LCD_BPP            BitsPerPixel;
+  VOID   *FrameBufferBase;
+
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  //
+  // BltVideo to BltVideo:
+  //
+  //  Source is the Video Memory,
+  //  Destination is the Video Memory
+
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  // The UEFI spec currently states:
+  // "There is no limitation on the overlapping of the source and destination rectangles"
+  // Therefore, we must be careful to avoid overwriting the source data
+  if( SourceY == DestinationY ) {
+    // Copying within the same height, e.g. horizontal shift
+    if( SourceX == DestinationX ) {
+      // Nothing to do
+      Status = EFI_SUCCESS;
+    } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {
+      // There is overlap
+      Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+    } else {
+      // No overlap
+      Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+    }
+  } else {
+    // Copying from different heights
+    Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+  }
+
+  return Status;
+}
+
+/***************************************
+ * GraphicsOutput Protocol function, mapping to
+ * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
+ *
+ * PRESUMES: 1 pixel = 4 bytes (32bits)
+ *  ***************************************/
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION   BltOperation,
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  UINT32             VerticalResolution;
+  LCD_INSTANCE*      Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  // Setup the hardware if not already done
+  if (!mDisplayInitialized) {
+    Status = InitializeDisplay (Instance);
+    if (EFI_ERROR(Status)) {
+      goto EXIT;
+    }
+  }
+
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  VerticalResolution   = This->Mode->Info->VerticalResolution;
+
+  DEBUG((DEBUG_INFO, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
+      BltOperation,DestinationX,DestinationY,Width,Height,HorizontalResolution,VerticalResolution));
+
+  // Check we have reasonable parameters
+  if (Width == 0 || Height == 0) {
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT;
+  }
+
+  if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) {
+    ASSERT( BltBuffer != NULL);
+  }
+
+  /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT;
+  }*/
+
+  // If we are reading data out of the video buffer, check that the source area is within the display limits
+  if ((BltOperation == EfiBltVideoToBltBuffer) || (BltOperation == EfiBltVideoToVideo)) {
+    if ((SourceY + Height > VerticalResolution) || (SourceX + Width > HorizontalResolution)) {
+      DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
+      DEBUG((DEBUG_INFO, "                      - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY, Height, VerticalResolution ));
+      DEBUG((DEBUG_INFO, "                      - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX, Width, HorizontalResolution ));
+      Status = EFI_INVALID_PARAMETER;
+      goto EXIT;
+    }
+  }
+
+  // If we are writing data into the video buffer, that the destination area is within the display limits
+  if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToVideo)) {
+    if ((DestinationY + Height > VerticalResolution) || (DestinationX + Width > HorizontalResolution)) {
+      DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
+      DEBUG((DEBUG_INFO, "                      - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY, Height, VerticalResolution ));
+      DEBUG((DEBUG_INFO, "                      - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX, Width, HorizontalResolution ));
+      Status = EFI_INVALID_PARAMETER;
+      goto EXIT;
+    }
+  }
+
+  //
+  // Perform the Block Transfer Operation
+  //
+
+  switch (BltOperation) {
+  case EfiBltVideoFill:
+    Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltVideoToBltBuffer:
+    Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltBufferToVideo:
+    Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltVideoToVideo:
+    Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiGraphicsOutputBltOperationMax:
+  default:
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));
+    Status = EFI_INVALID_PARAMETER;
+    break;
+  }
+
+EXIT:
+  return Status;
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
new file mode 100644
index 000000000000..b721061fc1df
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
@@ -0,0 +1,393 @@
+/** @file
+
+ Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+/**********************************************************************
+ *
+ *  This file implements the Graphics Output protocol on ArmVersatileExpress
+ *  using the Lcd controller
+ *
+ **********************************************************************/
+
+//
+// Global variables
+//
+
+BOOLEAN mDisplayInitialized = FALSE;
+
+LCD_INSTANCE mLcdTemplate = {
+  LCD_INSTANCE_SIGNATURE,
+  NULL, // Handle
+  { // ModeInfo
+    0, // Version
+    0, // HorizontalResolution
+    0, // VerticalResolution
+    PixelBltOnly, // PixelFormat
+    { 0 }, // PixelInformation
+    0, // PixelsPerScanLine
+  },
+  {
+    0, // MaxMode;
+    0, // Mode;
+    NULL, // Info;
+    0, // SizeOfInfo;
+    0, // FrameBufferBase;
+    0 // FrameBufferSize;
+  },
+  { // Gop
+    LcdGraphicsQueryMode,  // QueryMode
+    LcdGraphicsSetMode,    // SetMode
+    LcdGraphicsBlt,        // Blt
+    NULL                     // *Mode
+  },
+  { // DevicePath
+    {
+      {
+        HARDWARE_DEVICE_PATH, HW_VENDOR_DP,
+        { (UINT8) (sizeof(VENDOR_DEVICE_PATH)), (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8) },
+      },
+      // Hardware Device Path for Lcd
+      EFI_CALLER_ID_GUID // Use the driver's GUID
+    },
+
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0 }
+    }
+  },
+  (EFI_EVENT) NULL // ExitBootServicesEvent
+};
+
+EFI_STATUS
+LcdInstanceContructor (
+  OUT LCD_INSTANCE** NewInstance
+  )
+{
+  LCD_INSTANCE* Instance;
+
+  Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);
+  if (Instance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Instance->Gop.Mode          = &Instance->Mode;
+  Instance->Gop.Mode->MaxMode = LcdPlatformGetMaxMode ();
+  Instance->Mode.Info         = &Instance->ModeInfo;
+
+  *NewInstance = Instance;
+  return EFI_SUCCESS;
+}
+
+//
+// Function Definitions
+//
+
+EFI_STATUS
+InitializeDisplay (
+  IN LCD_INSTANCE* Instance
+  )
+{
+  EFI_STATUS             Status = EFI_SUCCESS;
+  EFI_PHYSICAL_ADDRESS   VramBaseAddress;
+  UINTN                  VramSize;
+
+  Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  // Setup the LCD
+  Status = LcdInitialize (VramBaseAddress);
+  if (EFI_ERROR(Status)) {
+    goto EXIT_ERROR_LCD_SHUTDOWN;
+  }
+
+  Status = LcdPlatformInitializeDisplay (Instance->Handle);
+  if (EFI_ERROR(Status)) {
+    goto EXIT_ERROR_LCD_SHUTDOWN;
+  }
+
+  // Setup all the relevant mode information
+  Instance->Gop.Mode->SizeOfInfo      = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+  Instance->Gop.Mode->FrameBufferBase = VramBaseAddress;
+
+  // Set the flag before changing the mode, to avoid infinite loops
+  mDisplayInitialized = TRUE;
+
+  // All is ok, so don't deal with any errors
+  goto EXIT;
+
+EXIT_ERROR_LCD_SHUTDOWN:
+  DEBUG((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status));
+  LcdShutdown ();
+
+EXIT:
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsOutputDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  LCD_INSTANCE* Instance;
+
+  Status = LcdIdentify ();
+  if (EFI_ERROR(Status)) {
+    goto EXIT;
+  }
+
+  Status = LcdInstanceContructor (&Instance);
+  if (EFI_ERROR(Status)) {
+    goto EXIT;
+  }
+
+  // Install the Graphics Output Protocol and the Device Path
+  Status = gBS->InstallMultipleProtocolInterfaces(
+            &Instance->Handle,
+            &gEfiGraphicsOutputProtocolGuid, &Instance->Gop,
+            &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,
+            NULL
+            );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));
+    goto EXIT;
+  }
+
+  // Register for an ExitBootServicesEvent
+  // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
+  // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
+  Status = gBS->CreateEvent (
+            EVT_SIGNAL_EXIT_BOOT_SERVICES,
+            TPL_NOTIFY,
+            LcdGraphicsExitBootServicesEvent, NULL,
+            &Instance->ExitBootServicesEvent
+            );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
+    goto EXIT_ERROR_UNINSTALL_PROTOCOL;
+  }
+
+  // To get here, everything must be fine, so just exit
+  goto EXIT;
+
+EXIT_ERROR_UNINSTALL_PROTOCOL:
+  /* The following function could return an error message,
+   * however, to get here something must have gone wrong already,
+   * so preserve the original error, i.e. don't change
+   * the Status variable, even it fails to uninstall the protocol.
+   */
+  gBS->UninstallMultipleProtocolInterfaces (
+    Instance->Handle,
+    &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
+    &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,     // Uninstall device path
+    NULL
+    );
+
+EXIT:
+  return Status;
+
+}
+
+/***************************************
+ * This function should be called
+ * on Event: ExitBootServices
+ * to free up memory, stop the driver
+ * and uninstall the protocols
+ ***************************************/
+VOID
+LcdGraphicsExitBootServicesEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  // By default, this PCD is FALSE. But if a platform starts a predefined OS that
+  // does not use a framebuffer then we might want to disable the display controller
+  // to avoid to display corrupted information on the screen.
+  if (FeaturePcdGet (PcdGopDisableOnExitBootServices)) {
+    // Turn-off the Display controller
+    LcdShutdown ();
+  }
+}
+
+/***************************************
+ * GraphicsOutput Protocol function, mapping to
+ * EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode
+ ***************************************/
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,
+  IN UINT32                                  ModeNumber,
+  OUT UINTN                                  *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   **Info
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  LCD_INSTANCE *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  // Setup the hardware if not already done
+  if( !mDisplayInitialized ) {
+    Status = InitializeDisplay(Instance);
+    if (EFI_ERROR(Status)) {
+      goto EXIT;
+    }
+  }
+
+  // Error checking
+  if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {
+    DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT;
+  }
+
+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+  if (*Info == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  *SizeOfInfo = sizeof( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+  Status = LcdPlatformQueryMode (ModeNumber,*Info);
+  if (EFI_ERROR(Status)) {
+    FreePool(*Info);
+  }
+
+EXIT:
+  return Status;
+}
+
+/***************************************
+ * GraphicsOutput Protocol function, mapping to
+ * EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode
+ ***************************************/
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL   *This,
+  IN UINT32                         ModeNumber
+  )
+{
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   FillColour;
+  LCD_INSTANCE*                   Instance;
+  LCD_BPP                         Bpp;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS (This);
+
+  // Setup the hardware if not already done
+  if(!mDisplayInitialized) {
+    Status = InitializeDisplay (Instance);
+    if (EFI_ERROR(Status)) {
+      goto EXIT;
+    }
+  }
+
+  // Check if this mode is supported
+  if( ModeNumber >= This->Mode->MaxMode ) {
+    DEBUG((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber ));
+    Status = EFI_UNSUPPORTED;
+    goto EXIT;
+  }
+
+  // Set the oscillator frequency to support the new mode
+  Status = LcdPlatformSetMode (ModeNumber);
+  if (EFI_ERROR(Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto EXIT;
+  }
+
+  // Update the UEFI mode information
+  This->Mode->Mode = ModeNumber;
+  LcdPlatformQueryMode (ModeNumber,&Instance->ModeInfo);
+  Status = LcdPlatformGetBpp(ModeNumber, &Bpp);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Couldn't get bytes per pixel, status: %r\n", Status));
+    goto EXIT;
+  }
+  This->Mode->FrameBufferSize =  Instance->ModeInfo.VerticalResolution
+                               * Instance->ModeInfo.PixelsPerScanLine
+                               * GetBytesPerPixel(Bpp);
+
+  // Set the hardware to the new mode
+  Status = LcdSetMode (ModeNumber);
+  if (EFI_ERROR(Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto EXIT;
+  }
+
+  // The UEFI spec requires that we now clear the visible portions of the output display to black.
+
+  // Set the fill colour to black
+  SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+
+  // Fill the entire visible area with the same colour.
+  Status = This->Blt (
+      This,
+      &FillColour,
+      EfiBltVideoFill,
+      0,
+      0,
+      0,
+      0,
+      This->Mode->Info->HorizontalResolution,
+      This->Mode->Info->VerticalResolution,
+      0);
+
+EXIT:
+  return Status;
+}
+
+UINTN
+GetBytesPerPixel (
+  IN  LCD_BPP       Bpp
+  )
+{
+  switch(Bpp) {
+  case LCD_BITS_PER_PIXEL_24:
+    return 4;
+
+  case LCD_BITS_PER_PIXEL_16_565:
+  case LCD_BITS_PER_PIXEL_16_555:
+  case LCD_BITS_PER_PIXEL_12_444:
+    return 2;
+
+  case LCD_BITS_PER_PIXEL_8:
+  case LCD_BITS_PER_PIXEL_4:
+  case LCD_BITS_PER_PIXEL_2:
+  case LCD_BITS_PER_PIXEL_1:
+    return 1;
+
+  default:
+    return 0;
+  }
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
new file mode 100644
index 000000000000..8856b79901b6
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
@@ -0,0 +1,128 @@
+/** @file
+
+  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM_VE_GRAPHICS_DXE_H__
+#define __ARM_VE_GRAPHICS_DXE_H__
+
+
+#include <Base.h>
+
+#include <Library/DebugLib.h>
+#include <Library/LcdPlatformLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/DevicePath.h>
+
+
+//
+// Device structures
+//
+typedef struct {
+  VENDOR_DEVICE_PATH            Guid;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} LCD_GRAPHICS_DEVICE_PATH;
+
+typedef struct {
+  UINT32                                Signature;
+  EFI_HANDLE                            Handle;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  ModeInfo;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE     Mode;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          Gop;
+  LCD_GRAPHICS_DEVICE_PATH              DevicePath;
+  EFI_EVENT                             ExitBootServicesEvent;
+} LCD_INSTANCE;
+
+#define LCD_INSTANCE_SIGNATURE  SIGNATURE_32('l', 'c', 'd', '0')
+
+#define LCD_INSTANCE_FROM_GOP_THIS(a)     CR (a, LCD_INSTANCE, Gop, LCD_INSTANCE_SIGNATURE)
+
+//
+// Function Prototypes
+//
+
+VOID
+LcdGraphicsExitBootServicesEvent (
+    IN EFI_EVENT  Event,
+    IN VOID       *Context
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
+  IN  UINT32                                ModeNumber,
+  OUT UINTN                                 *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,
+  IN UINT32                        ModeNumber
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL       *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer,     OPTIONAL
+  IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,
+  IN UINTN                              SourceX,
+  IN UINTN                              SourceY,
+  IN UINTN                              DestinationX,
+  IN UINTN                              DestinationY,
+  IN UINTN                              Width,
+  IN UINTN                              Height,
+  IN UINTN                              Delta           OPTIONAL
+);
+
+UINTN
+GetBytesPerPixel (
+  IN  LCD_BPP       Bpp
+  );
+
+EFI_STATUS
+EFIAPI
+GraphicsOutputDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+);
+
+EFI_STATUS
+InitializeDisplay (
+  IN LCD_INSTANCE* Instance
+);
+
+EFI_STATUS
+LcdIdentify (
+  VOID
+);
+
+EFI_STATUS
+LcdInitialize (
+  EFI_PHYSICAL_ADDRESS  VramBaseAddress
+);
+
+EFI_STATUS
+LcdSetMode (
+  IN UINT32  ModeNumber
+);
+
+VOID
+LcdShutdown (
+  VOID
+);
+
+#endif /* __ARM_VE_GRAPHICS_DXE_H__ */
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c
new file mode 100644
index 000000000000..b5e113b844d4
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c
@@ -0,0 +1,126 @@
+/** @file  PL111Lcd.c
+
+  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Drivers/PL111Lcd.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+/**********************************************************************
+ *
+ *  This file contains all the bits of the PL111 that are
+ *  platform independent.
+ *
+ **********************************************************************/
+
+EFI_STATUS
+LcdIdentify (
+  VOID
+  )
+{
+  DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL111\n",
+    PL111_REG_CLCD_PERIPH_ID_0));
+
+  // Check if this is a PL111
+  if (MmioRead8 (PL111_REG_CLCD_PERIPH_ID_0) == PL111_CLCD_PERIPH_ID_0 &&
+      MmioRead8 (PL111_REG_CLCD_PERIPH_ID_1) == PL111_CLCD_PERIPH_ID_1 &&
+     (MmioRead8 (PL111_REG_CLCD_PERIPH_ID_2) & 0xf) == PL111_CLCD_PERIPH_ID_2 &&
+      MmioRead8 (PL111_REG_CLCD_PERIPH_ID_3) == PL111_CLCD_PERIPH_ID_3 &&
+      MmioRead8 (PL111_REG_CLCD_P_CELL_ID_0) == PL111_CLCD_P_CELL_ID_0 &&
+      MmioRead8 (PL111_REG_CLCD_P_CELL_ID_1) == PL111_CLCD_P_CELL_ID_1 &&
+      MmioRead8 (PL111_REG_CLCD_P_CELL_ID_2) == PL111_CLCD_P_CELL_ID_2 &&
+      MmioRead8 (PL111_REG_CLCD_P_CELL_ID_3) == PL111_CLCD_P_CELL_ID_3) {
+    return EFI_SUCCESS;
+  }
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+LcdInitialize (
+  IN EFI_PHYSICAL_ADDRESS   VramBaseAddress
+  )
+{
+  // Define start of the VRAM. This never changes for any graphics mode
+  MmioWrite32(PL111_REG_LCD_UP_BASE, (UINT32) VramBaseAddress);
+  MmioWrite32(PL111_REG_LCD_LP_BASE, 0); // We are not using a double buffer
+
+  // Disable all interrupts from the PL111
+  MmioWrite32(PL111_REG_LCD_IMSC, 0);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdSetMode (
+  IN UINT32  ModeNumber
+  )
+{
+  EFI_STATUS        Status;
+  UINT32            HRes;
+  UINT32            HSync;
+  UINT32            HBackPorch;
+  UINT32            HFrontPorch;
+  UINT32            VRes;
+  UINT32            VSync;
+  UINT32            VBackPorch;
+  UINT32            VFrontPorch;
+  UINT32            LcdControl;
+  LCD_BPP           LcdBpp;
+
+  // Set the video mode timings and other relevant information
+  Status = LcdPlatformGetTimings (ModeNumber,
+                                  &HRes,&HSync,&HBackPorch,&HFrontPorch,
+                                  &VRes,&VSync,&VBackPorch,&VFrontPorch);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR( Status )) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = LcdPlatformGetBpp (ModeNumber,&LcdBpp);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR( Status )) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  // Disable the CLCD_LcdEn bit
+  LcdControl = MmioRead32( PL111_REG_LCD_CONTROL);
+  MmioWrite32(PL111_REG_LCD_CONTROL,  LcdControl & ~1);
+
+  // Set Timings
+  MmioWrite32 (PL111_REG_LCD_TIMING_0, HOR_AXIS_PANEL(HBackPorch, HFrontPorch, HSync, HRes));
+  MmioWrite32 (PL111_REG_LCD_TIMING_1, VER_AXIS_PANEL(VBackPorch, VFrontPorch, VSync, VRes));
+  MmioWrite32 (PL111_REG_LCD_TIMING_2, CLK_SIG_POLARITY(HRes));
+  MmioWrite32 (PL111_REG_LCD_TIMING_3, 0);
+
+  // PL111_REG_LCD_CONTROL
+  LcdControl = PL111_CTRL_LCD_EN | PL111_CTRL_LCD_BPP(LcdBpp) | PL111_CTRL_LCD_TFT | PL111_CTRL_BGR;
+  MmioWrite32(PL111_REG_LCD_CONTROL,  LcdControl);
+
+  // Turn on power to the LCD Panel
+  LcdControl |= PL111_CTRL_LCD_PWR;
+  MmioWrite32(PL111_REG_LCD_CONTROL,  LcdControl);
+
+  return EFI_SUCCESS;
+}
+
+VOID
+LcdShutdown (
+  VOID
+  )
+{
+  // Disable the controller
+  MmioAnd32 (PL111_REG_LCD_CONTROL, ~PL111_CTRL_LCD_EN);
+}
diff --git a/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
new file mode 100644
index 000000000000..003cc2ffa912
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
@@ -0,0 +1,59 @@
+#/** @file
+#
+#  Component description file for PL111LcdGraphicsOutputDxe module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PL111LcdGraphicsDxe
+  FILE_GUID                      = 407B4008-BF5B-11DF-9547-CF16E0D72085
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = LcdGraphicsOutputDxeInitialize
+
+[Sources.common]
+  LcdGraphicsOutputDxe.c
+  LcdGraphicsOutputBlt.c
+  PL111Lcd.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  UefiLib
+  BaseLib
+  DebugLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  IoLib
+  BaseMemoryLib
+  LcdPlatformLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdPL111LcdBase
+
+[FeaturePcd]
+  gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices
+
+[Depex]
+  gEfiCpuArchProtocolGuid
diff --git a/Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h b/Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h
new file mode 100644
index 000000000000..6df97a9dfee6
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/Drivers/HdLcd.h
@@ -0,0 +1,89 @@
+/** @file  HDLcd.h
+
+ Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#ifndef _HDLCD_H_
+#define _HDLCD_H_
+
+//
+// HDLCD Controller Register Offsets
+//
+
+#define HDLCD_REG_VERSION                 ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x000)
+#define HDLCD_REG_INT_RAWSTAT             ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x010)
+#define HDLCD_REG_INT_CLEAR               ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x014)
+#define HDLCD_REG_INT_MASK                ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x018)
+#define HDLCD_REG_INT_STATUS              ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x01C)
+#define HDLCD_REG_FB_BASE                 ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x100)
+#define HDLCD_REG_FB_LINE_LENGTH          ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x104)
+#define HDLCD_REG_FB_LINE_COUNT           ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x108)
+#define HDLCD_REG_FB_LINE_PITCH           ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x10C)
+#define HDLCD_REG_BUS_OPTIONS             ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x110)
+#define HDLCD_REG_V_SYNC                  ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x200)
+#define HDLCD_REG_V_BACK_PORCH            ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x204)
+#define HDLCD_REG_V_DATA                  ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x208)
+#define HDLCD_REG_V_FRONT_PORCH           ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x20C)
+#define HDLCD_REG_H_SYNC                  ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x210)
+#define HDLCD_REG_H_BACK_PORCH            ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x214)
+#define HDLCD_REG_H_DATA                  ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x218)
+#define HDLCD_REG_H_FRONT_PORCH           ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x21C)
+#define HDLCD_REG_POLARITIES              ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x220)
+#define HDLCD_REG_COMMAND                 ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x230)
+#define HDLCD_REG_PIXEL_FORMAT            ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x240)
+#define HDLCD_REG_RED_SELECT              ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x244)
+#define HDLCD_REG_GREEN_SELECT            ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x248)
+#define HDLCD_REG_BLUE_SELECT             ((UINTN)PcdGet32 (PcdArmHdLcdBase) + 0x24C)
+
+
+//
+// HDLCD Values of registers
+//
+
+// HDLCD Interrupt mask, clear and status register
+#define HDLCD_DMA_END                     BIT0    /* DMA has finished reading a frame */
+#define HDLCD_BUS_ERROR                   BIT1    /* DMA bus error */
+#define HDLCD_SYNC                        BIT2    /* Vertical sync */
+#define HDLCD_UNDERRUN                    BIT3    /* No Data available while DATAEN active */
+
+// CLCD_CONTROL Control register
+#define HDLCD_DISABLE                     0
+#define HDLCD_ENABLE                      BIT0
+
+// Bus Options
+#define HDLCD_BURST_1                     BIT0
+#define HDLCD_BURST_2                     BIT1
+#define HDLCD_BURST_4                     BIT2
+#define HDLCD_BURST_8                     BIT3
+#define HDLCD_BURST_16                    BIT4
+
+// Polarities - HIGH
+#define HDLCD_VSYNC_HIGH                  BIT0
+#define HDLCD_HSYNC_HIGH                  BIT1
+#define HDLCD_DATEN_HIGH                  BIT2
+#define HDLCD_DATA_HIGH                   BIT3
+#define HDLCD_PXCLK_HIGH                  BIT4
+// Polarities - LOW (for completion and for ease of understanding the hardware settings)
+#define HDLCD_VSYNC_LOW                   0
+#define HDLCD_HSYNC_LOW                   0
+#define HDLCD_DATEN_LOW                   0
+#define HDLCD_DATA_LOW                    0
+#define HDLCD_PXCLK_LOW                   0
+
+// Pixel Format
+#define HDLCD_LITTLE_ENDIAN              (0 << 31)
+#define HDLCD_BIG_ENDIAN                 (1 << 31)
+
+// Number of bytes per pixel
+#define HDLCD_4BYTES_PER_PIXEL           ((4 - 1) << 3)
+
+#endif /* _HDLCD_H_ */
diff --git a/Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h b/Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h
new file mode 100644
index 000000000000..18e28af805f6
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/Drivers/PL111Lcd.h
@@ -0,0 +1,149 @@
+/** @file  PL111Lcd.h
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#ifndef _PL111LCD_H__
+#define _PL111LCD_H__
+
+/**********************************************************************
+ *
+ *  This header file contains all the bits of the PL111 that are
+ *  platform independent.
+ *
+ **********************************************************************/
+
+// Controller Register Offsets
+#define PL111_REG_LCD_TIMING_0            ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x000)
+#define PL111_REG_LCD_TIMING_1            ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x004)
+#define PL111_REG_LCD_TIMING_2            ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x008)
+#define PL111_REG_LCD_TIMING_3            ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x00C)
+#define PL111_REG_LCD_UP_BASE             ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x010)
+#define PL111_REG_LCD_LP_BASE             ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x014)
+#define PL111_REG_LCD_CONTROL             ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x018)
+#define PL111_REG_LCD_IMSC                ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x01C)
+#define PL111_REG_LCD_RIS                 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x020)
+#define PL111_REG_LCD_MIS                 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x024)
+#define PL111_REG_LCD_ICR                 ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x028)
+#define PL111_REG_LCD_UP_CURR             ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x02C)
+#define PL111_REG_LCD_LP_CURR             ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x030)
+#define PL111_REG_LCD_PALETTE             ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0x200)
+
+// Identification Register Offsets
+#define PL111_REG_CLCD_PERIPH_ID_0        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFE0)
+#define PL111_REG_CLCD_PERIPH_ID_1        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFE4)
+#define PL111_REG_CLCD_PERIPH_ID_2        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFE8)
+#define PL111_REG_CLCD_PERIPH_ID_3        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFEC)
+#define PL111_REG_CLCD_P_CELL_ID_0        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFF0)
+#define PL111_REG_CLCD_P_CELL_ID_1        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFF4)
+#define PL111_REG_CLCD_P_CELL_ID_2        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFF8)
+#define PL111_REG_CLCD_P_CELL_ID_3        ((UINTN)PcdGet32 (PcdPL111LcdBase) + 0xFFC)
+
+#define PL111_CLCD_PERIPH_ID_0            0x11
+#define PL111_CLCD_PERIPH_ID_1            0x11
+#define PL111_CLCD_PERIPH_ID_2            0x04
+#define PL111_CLCD_PERIPH_ID_3            0x00
+#define PL111_CLCD_P_CELL_ID_0            0x0D
+#define PL111_CLCD_P_CELL_ID_1            0xF0
+#define PL111_CLCD_P_CELL_ID_2            0x05
+#define PL111_CLCD_P_CELL_ID_3            0xB1
+
+/**********************************************************************/
+
+// Register components (register bits)
+
+// This should make life easier to program specific settings in the different registers
+// by simplifying the setting up of the individual bits of each register
+// and then assembling the final register value.
+
+/**********************************************************************/
+
+// Register: PL111_REG_LCD_TIMING_0
+#define HOR_AXIS_PANEL(hbp,hfp,hsw,hor_res) (UINT32)(((UINT32)(hbp) << 24) | ((UINT32)(hfp) << 16) | ((UINT32)(hsw) << 8) | (((UINT32)((hor_res)/16)-1) << 2))
+
+// Register: PL111_REG_LCD_TIMING_1
+#define VER_AXIS_PANEL(vbp,vfp,vsw,ver_res) (UINT32)(((UINT32)(vbp) << 24) | ((UINT32)(vfp) << 16) | ((UINT32)(vsw) << 10) | ((ver_res)-1))
+
+// Register: PL111_REG_LCD_TIMING_2
+#define PL111_BIT_SHIFT_PCD_HI            27
+#define PL111_BIT_SHIFT_BCD               26
+#define PL111_BIT_SHIFT_CPL               16
+#define PL111_BIT_SHIFT_IOE               14
+#define PL111_BIT_SHIFT_IPC               13
+#define PL111_BIT_SHIFT_IHS               12
+#define PL111_BIT_SHIFT_IVS               11
+#define PL111_BIT_SHIFT_ACB               6
+#define PL111_BIT_SHIFT_CLKSEL            5
+#define PL111_BIT_SHIFT_PCD_LO            0
+
+#define PL111_BCD                         (1 << 26)
+#define PL111_IPC                         (1 << 13)
+#define PL111_IHS                         (1 << 12)
+#define PL111_IVS                         (1 << 11)
+
+#define CLK_SIG_POLARITY(hor_res)         (UINT32)(PL111_BCD | PL111_IPC | PL111_IHS | PL111_IVS | (((hor_res)-1) << 16))
+
+// Register: PL111_REG_LCD_TIMING_3
+#define PL111_BIT_SHIFT_LEE               16
+#define PL111_BIT_SHIFT_LED               0
+
+#define PL111_CTRL_WATERMARK              (1 << 16)
+#define PL111_CTRL_LCD_V_COMP             (1 << 12)
+#define PL111_CTRL_LCD_PWR                (1 << 11)
+#define PL111_CTRL_BEPO                   (1 << 10)
+#define PL111_CTRL_BEBO                   (1 << 9)
+#define PL111_CTRL_BGR                    (1 << 8)
+#define PL111_CTRL_LCD_DUAL               (1 << 7)
+#define PL111_CTRL_LCD_MONO_8             (1 << 6)
+#define PL111_CTRL_LCD_TFT                (1 << 5)
+#define PL111_CTRL_LCD_BW                 (1 << 4)
+#define PL111_CTRL_LCD_1BPP               (0 << 1)
+#define PL111_CTRL_LCD_2BPP               (1 << 1)
+#define PL111_CTRL_LCD_4BPP               (2 << 1)
+#define PL111_CTRL_LCD_8BPP               (3 << 1)
+#define PL111_CTRL_LCD_16BPP              (4 << 1)
+#define PL111_CTRL_LCD_24BPP              (5 << 1)
+#define PL111_CTRL_LCD_16BPP_565          (6 << 1)
+#define PL111_CTRL_LCD_12BPP_444          (7 << 1)
+#define PL111_CTRL_LCD_BPP(Bpp)           ((Bpp) << 1)
+#define PL111_CTRL_LCD_EN                 1
+
+/**********************************************************************/
+
+// Register: PL111_REG_LCD_TIMING_0
+#define PL111_LCD_TIMING_0_HBP(hbp)       (((hbp) & 0xFF) << 24)
+#define PL111_LCD_TIMING_0_HFP(hfp)       (((hfp) & 0xFF) << 16)
+#define PL111_LCD_TIMING_0_HSW(hsw)       (((hsw) & 0xFF) << 8)
+#define PL111_LCD_TIMING_0_PPL(ppl)       (((hsw) & 0x3F) << 2)
+
+// Register: PL111_REG_LCD_TIMING_1
+#define PL111_LCD_TIMING_1_VBP(vbp)       (((vbp) & 0xFF) << 24)
+#define PL111_LCD_TIMING_1_VFP(vfp)       (((vfp) & 0xFF) << 16)
+#define PL111_LCD_TIMING_1_VSW(vsw)       (((vsw) & 0x3F) << 10)
+#define PL111_LCD_TIMING_1_LPP(lpp)        ((lpp) & 0xFC)
+
+// Register: PL111_REG_LCD_TIMING_2
+#define PL111_BIT_MASK_PCD_HI             0xF8000000
+#define PL111_BIT_MASK_BCD                0x04000000
+#define PL111_BIT_MASK_CPL                0x03FF0000
+#define PL111_BIT_MASK_IOE                0x00004000
+#define PL111_BIT_MASK_IPC                0x00002000
+#define PL111_BIT_MASK_IHS                0x00001000
+#define PL111_BIT_MASK_IVS                0x00000800
+#define PL111_BIT_MASK_ACB                0x000007C0
+#define PL111_BIT_MASK_CLKSEL             0x00000020
+#define PL111_BIT_MASK_PCD_LO             0x0000001F
+
+// Register: PL111_REG_LCD_TIMING_3
+#define PL111_BIT_MASK_LEE                0x00010000
+#define PL111_BIT_MASK_LED                0x0000007F
+
+#endif /* _PL111LCD_H__ */
diff --git a/Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h b/Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h
new file mode 100644
index 000000000000..39a0cc7f734c
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/Library/ArmPlatformSysConfigLib.h
@@ -0,0 +1,63 @@
+/** @file  ArmPlatformSysConfigLib.h
+
+  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM_PLATFORM_SYS_CONFIG_H__
+#define __ARM_PLATFORM_SYS_CONFIG_H__
+
+#include <Base.h>
+
+/* This header file makes it easier to access the System Configuration Registers
+ * in the ARM Versatile Express motherboard.
+ */
+
+//
+// Typedef
+//
+typedef UINT32  SYS_CONFIG_FUNCTION;
+
+//
+// Functions
+//
+RETURN_STATUS
+ArmPlatformSysConfigInitialize (
+  VOID
+  );
+
+RETURN_STATUS
+ArmPlatformSysConfigGet (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  OUT UINT32*               Value
+  );
+
+RETURN_STATUS
+ArmPlatformSysConfigGetValues (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINTN                 Size,
+  OUT UINT32*               Values
+  );
+
+RETURN_STATUS
+ArmPlatformSysConfigSet (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINT32                Value
+  );
+
+RETURN_STATUS
+ArmPlatformSysConfigSetDevice (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINT32                Device,
+  IN  UINT32                Value
+  );
+
+#endif /* __SYS_CFG_REGISTERS_H__ */
diff --git a/Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h b/Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h
new file mode 100644
index 000000000000..b9bdf471e2d6
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/Library/LcdPlatformLib.h
@@ -0,0 +1,221 @@
+/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#ifndef __LCDPLATFORMLIB_H
+#define __LCDPLATFORMLIB_H
+
+#include <Protocol/GraphicsOutput.h>
+
+#define LCD_VRAM_SIZE                     SIZE_8MB
+
+//
+// Modes definitions
+//
+#define VGA                               0
+#define SVGA                              1
+#define XGA                               2
+#define SXGA                              3
+#define WSXGA                             4
+#define UXGA                              5
+#define HD                                6
+
+//
+// VGA Mode: 640 x 480
+//
+#define VGA_H_RES_PIXELS                  640
+#define VGA_V_RES_PIXELS                  480
+#define VGA_OSC_FREQUENCY                 23750000  /* 0x016A6570 */
+
+#define VGA_H_SYNC                        ( 80 - 1)
+#define VGA_H_FRONT_PORCH                 ( 16 - 1)
+#define VGA_H_BACK_PORCH                  ( 64 - 1)
+
+#define VGA_V_SYNC                        (  4 - 1)
+#define VGA_V_FRONT_PORCH                 (  3 - 1)
+#define VGA_V_BACK_PORCH                  ( 13 - 1)
+
+//
+// SVGA Mode: 800 x 600
+//
+#define SVGA_H_RES_PIXELS                 800
+#define SVGA_V_RES_PIXELS                 600
+#define SVGA_OSC_FREQUENCY                38250000  /* 0x0247A610 */
+
+#define SVGA_H_SYNC                       ( 80 - 1)
+#define SVGA_H_FRONT_PORCH                ( 32 - 1)
+#define SVGA_H_BACK_PORCH                 (112 - 1)
+
+#define SVGA_V_SYNC                       (  4 - 1)
+#define SVGA_V_FRONT_PORCH                (  3 - 1)
+#define SVGA_V_BACK_PORCH                 ( 17 - 1)
+
+//
+// XGA Mode: 1024 x 768
+//
+#define XGA_H_RES_PIXELS                  1024
+#define XGA_V_RES_PIXELS                  768
+#define XGA_OSC_FREQUENCY                 63500000  /* 0x03C8EEE0 */
+
+#define XGA_H_SYNC                        (104 - 1)
+#define XGA_H_FRONT_PORCH                 ( 48 - 1)
+#define XGA_H_BACK_PORCH                  (152 - 1)
+
+#define XGA_V_SYNC                        (  4 - 1)
+#define XGA_V_FRONT_PORCH                 (  3 - 1)
+#define XGA_V_BACK_PORCH                  ( 23 - 1)
+
+//
+// SXGA Mode: 1280 x 1024
+//
+#define SXGA_H_RES_PIXELS                 1280
+#define SXGA_V_RES_PIXELS                 1024
+#define SXGA_OSC_FREQUENCY                109000000  /* 0x067F3540 */
+
+#define SXGA_H_SYNC                       (136 - 1)
+#define SXGA_H_FRONT_PORCH                ( 80 - 1)
+#define SXGA_H_BACK_PORCH                 (216 - 1)
+
+#define SXGA_V_SYNC                       (  7 - 1)
+#define SXGA_V_FRONT_PORCH                (  3 - 1)
+#define SXGA_V_BACK_PORCH                 ( 29 - 1)
+
+//
+// WSXGA+ Mode: 1680 x 1050
+//
+#define WSXGA_H_RES_PIXELS                1680
+#define WSXGA_V_RES_PIXELS                1050
+#define WSXGA_OSC_FREQUENCY               147000000  /* 0x08C30AC0 */
+
+#define WSXGA_H_SYNC                      (170 - 1)
+#define WSXGA_H_FRONT_PORCH               (104 - 1)
+#define WSXGA_H_BACK_PORCH                (274 - 1)
+
+#define WSXGA_V_SYNC                      (  5 - 1)
+#define WSXGA_V_FRONT_PORCH               (  4 - 1)
+#define WSXGA_V_BACK_PORCH                ( 41 - 1)
+
+//
+// UXGA Mode: 1600 x 1200
+//
+#define UXGA_H_RES_PIXELS                 1600
+#define UXGA_V_RES_PIXELS                 1200
+#define UXGA_OSC_FREQUENCY                161000000  /* 0x0998AA40 */
+
+#define UXGA_H_SYNC                       (168 - 1)
+#define UXGA_H_FRONT_PORCH                (112 - 1)
+#define UXGA_H_BACK_PORCH                 (280 - 1)
+
+#define UXGA_V_SYNC                       (  4 - 1)
+#define UXGA_V_FRONT_PORCH                (  3 - 1)
+#define UXGA_V_BACK_PORCH                 ( 38 - 1)
+
+//
+// HD Mode: 1920 x 1080
+//
+#define HD_H_RES_PIXELS                   1920
+#define HD_V_RES_PIXELS                   1080
+#define HD_OSC_FREQUENCY                  165000000  /* 0x09D5B340 */
+
+#define HD_H_SYNC                         ( 79 - 1)
+#define HD_H_FRONT_PORCH                  (128 - 1)
+#define HD_H_BACK_PORCH                   (328 - 1)
+
+#define HD_V_SYNC                         (  5 - 1)
+#define HD_V_FRONT_PORCH                  (  3 - 1)
+#define HD_V_BACK_PORCH                   ( 32 - 1)
+
+//
+// Colour Masks
+//
+
+#define LCD_24BPP_RED_MASK              0x00FF0000
+#define LCD_24BPP_GREEN_MASK            0x0000FF00
+#define LCD_24BPP_BLUE_MASK             0x000000FF
+#define LCD_24BPP_RESERVED_MASK         0xFF000000
+
+#define LCD_16BPP_555_RED_MASK          0x00007C00
+#define LCD_16BPP_555_GREEN_MASK        0x000003E0
+#define LCD_16BPP_555_BLUE_MASK         0x0000001F
+#define LCD_16BPP_555_RESERVED_MASK     0x00000000
+
+#define LCD_16BPP_565_RED_MASK          0x0000F800
+#define LCD_16BPP_565_GREEN_MASK        0x000007E0
+#define LCD_16BPP_565_BLUE_MASK         0x0000001F
+#define LCD_16BPP_565_RESERVED_MASK     0x00008000
+
+#define LCD_12BPP_444_RED_MASK          0x00000F00
+#define LCD_12BPP_444_GREEN_MASK        0x000000F0
+#define LCD_12BPP_444_BLUE_MASK         0x0000000F
+#define LCD_12BPP_444_RESERVED_MASK     0x0000F000
+
+
+// The enumeration indexes maps the PL111 LcdBpp values used in the LCD Control Register
+typedef enum {
+  LCD_BITS_PER_PIXEL_1 = 0,
+  LCD_BITS_PER_PIXEL_2,
+  LCD_BITS_PER_PIXEL_4,
+  LCD_BITS_PER_PIXEL_8,
+  LCD_BITS_PER_PIXEL_16_555,
+  LCD_BITS_PER_PIXEL_24,
+  LCD_BITS_PER_PIXEL_16_565,
+  LCD_BITS_PER_PIXEL_12_444
+} LCD_BPP;
+
+
+EFI_STATUS
+LcdPlatformInitializeDisplay (
+  IN EFI_HANDLE   Handle
+  );
+
+EFI_STATUS
+LcdPlatformGetVram (
+  OUT EFI_PHYSICAL_ADDRESS*                 VramBaseAddress,
+  OUT UINTN*                                VramSize
+  );
+
+UINT32
+LcdPlatformGetMaxMode (
+  VOID
+  );
+
+EFI_STATUS
+LcdPlatformSetMode (
+  IN UINT32                                 ModeNumber
+  );
+
+EFI_STATUS
+LcdPlatformQueryMode (
+  IN  UINT32                                ModeNumber,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
+  );
+
+EFI_STATUS
+LcdPlatformGetTimings (
+  IN  UINT32                              ModeNumber,
+  OUT UINT32*                             HRes,
+  OUT UINT32*                             HSync,
+  OUT UINT32*                             HBackPorch,
+  OUT UINT32*                             HFrontPorch,
+  OUT UINT32*                             VRes,
+  OUT UINT32*                             VSync,
+  OUT UINT32*                             VBackPorch,
+  OUT UINT32*                             VFrontPorch
+  );
+
+EFI_STATUS
+LcdPlatformGetBpp (
+  IN  UINT32                                ModeNumber,
+  OUT LCD_BPP*                              Bpp
+  );
+
+#endif
diff --git a/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h b/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h
new file mode 100644
index 000000000000..b52f89a5cbf8
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/Platform/CTA15-A7/ArmPlatform.h
@@ -0,0 +1,154 @@
+/** @file
+*  Header defining Versatile Express constants (Base addresses, sizes, flags)
+*
+*  Copyright (c) 2012, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __ARM_VEXPRESS_CTA15A7_H__
+#define __ARM_VEXPRESS_CTA15A7_H__
+
+#include <VExpressMotherBoard.h>
+
+/***********************************************************************************
+// Platform Memory Map
+************************************************************************************/
+
+// Motherboard Peripheral and On-chip peripheral
+#define ARM_VE_BOARD_PERIPH_BASE              0x1C010000
+
+#ifdef ARM_BIGLITTLE_TC2
+
+// Secure NOR Flash
+#define ARM_VE_SEC_NOR0_BASE                  0x00000000
+#define ARM_VE_SEC_NOR0_SZ                    SIZE_64MB
+
+// Secure RAM
+#define ARM_VE_SEC_RAM0_BASE                  0x04000000
+#define ARM_VE_SEC_RAM0_SZ                    SIZE_64MB
+
+#endif
+
+// NOR Flash 0
+#define ARM_VE_SMB_NOR0_BASE                  0x08000000
+#define ARM_VE_SMB_NOR0_SZ                    SIZE_64MB
+// NOR Flash 1
+#define ARM_VE_SMB_NOR1_BASE                  0x0C000000
+#define ARM_VE_SMB_NOR1_SZ                    SIZE_64MB
+
+// SRAM
+#define ARM_VE_SMB_SRAM_BASE                  0x14000000
+#define ARM_VE_SMB_SRAM_SZ                    SIZE_32MB
+
+// USB, Ethernet, VRAM
+#ifdef ARM_BIGLITTLE_TC2
+#define ARM_VE_SMB_PERIPH_BASE                0x18000000
+#define ARM_VE_SMB_PERIPH_SZ                  (SIZE_64MB + SIZE_32MB + SIZE_16MB)
+#else
+#define ARM_VE_SMB_PERIPH_BASE                0x1C000000
+#define ARM_VE_SMB_PERIPH_SZ                  (SIZE_64MB + SIZE_16MB)
+#endif
+#define PL111_CLCD_VRAM_MOTHERBOARD_BASE      ARM_VE_SMB_PERIPH_BASE
+
+// On-Chip non-secure ROM
+#ifdef ARM_BIGLITTLE_TC2
+#define ARM_VE_TC2_NON_SECURE_ROM_BASE        0x1F000000
+#define ARM_VE_TC2_NON_SECURE_ROM_SZ          SIZE_16MB
+#endif
+
+// On-Chip Peripherals
+#define ARM_VE_ONCHIP_PERIPH_BASE             0x20000000
+#define ARM_VE_ONCHIP_PERIPH_SZ               0x10000000
+
+// On-Chip non-secure SRAM
+#ifdef ARM_BIGLITTLE_TC2
+#define ARM_VE_TC2_NON_SECURE_SRAM_BASE       0x2E000000
+#define ARM_VE_TC2_NON_SECURE_SRAM_SZ         SIZE_64KB
+#endif
+
+// Allocate a section for the VRAM (Video RAM)
+// If 0 then allow random memory allocation
+#define LCD_VRAM_CORE_TILE_BASE               0
+
+// Define SEC phase sync point
+#define ARM_SEC_EVENT_BOOT_IMAGE_TABLE_IS_AVAILABLE   (ARM_SEC_EVENT_MAX + 1)
+
+/***********************************************************************************
+   Core Tile memory-mapped Peripherals
+************************************************************************************/
+
+// PL354 Static Memory Controller Base
+#ifdef ARM_BIGLITTLE_TC2
+#define ARM_VE_SMC_CTRL_BASE                    0x7FFD0000
+#else
+#define ARM_VE_SMC_CTRL_BASE                    (ARM_VE_BOARD_PERIPH_BASE + 0xE1000)
+#endif
+
+#define ARM_CTA15A7_SCC_BASE                    0x7FFF0000
+#define ARM_CTA15A7_SCC_CFGREG48                (ARM_CTA15A7_SCC_BASE + 0x700)
+
+#define ARM_CTA15A7_SCC_SYSINFO                 ARM_CTA15A7_SCC_CFGREG48
+
+#define ARM_CTA15A7_SCC_SYSINFO_CLUSTER_A7_NUM_CPU(val)         (((val) >> 20) & 0xF)
+#define ARM_CTA15A7_SCC_SYSINFO_CLUSTER_A15_NUM_CPU(val)        (((val) >> 16) & 0xF)
+#define ARM_CTA15A7_SCC_SYSINFO_ACTIVE_CLUSTER_A15              (1 << 0)
+#define ARM_CTA15A7_SCC_SYSINFO_ACTIVE_CLUSTER_A7               (1 << 1)
+#define ARM_CTA15A7_SCC_SYSINFO_UEFI_RESTORE_DEFAULT_NORFLASH   (1 << 4)
+
+#define ARM_CTA15A7_SPC_BASE                    0x7FFF0B00
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK           (ARM_CTA15A7_SPC_BASE + 0x24)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT         (ARM_CTA15A7_SPC_BASE + 0x3C)
+#define ARM_CTA15A7_SPC_A15_BX_ADDR0            (ARM_CTA15A7_SPC_BASE + 0x68)
+#define ARM_CTA15A7_SPC_A15_BX_ADDR1            (ARM_CTA15A7_SPC_BASE + 0x6C)
+#define ARM_CTA15A7_SPC_A15_BX_ADDR2            (ARM_CTA15A7_SPC_BASE + 0x70)
+#define ARM_CTA15A7_SPC_A15_BX_ADDR3            (ARM_CTA15A7_SPC_BASE + 0x74)
+#define ARM_CTA15A7_SPC_A7_BX_ADDR0             (ARM_CTA15A7_SPC_BASE + 0x78)
+#define ARM_CTA15A7_SPC_A7_BX_ADDR1             (ARM_CTA15A7_SPC_BASE + 0x7C)
+#define ARM_CTA15A7_SPC_A7_BX_ADDR2             (ARM_CTA15A7_SPC_BASE + 0x80)
+#define ARM_CTA15A7_SPC_A7_BX_ADDR3             (ARM_CTA15A7_SPC_BASE + 0x84)
+
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A15_MASK_0  (1 << 0)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A15_MASK_1  (1 << 1)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A15_MASK_0  (1 << 2)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A15_MASK_1  (1 << 3)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A7_MASK_0   (1 << 4)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A7_MASK_1   (1 << 5)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_IRQ_A7_MASK_2   (1 << 6)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A7_MASK_0   (1 << 7)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A7_MASK_1   (1 << 8)
+#define ARM_CTA15A7_SPC_WAKE_INT_MASK_FIQ_A7_MASK_2   (1 << 9)
+
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A15_0   (1 << 0)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A15_1   (1 << 1)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A15_L2  (1 << 2)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_0    (1 << 3)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_1    (1 << 4)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_2    (1 << 5)
+#define ARM_CTA15A7_SPC_STANDBYWFI_STAT_A7_L2   (1 << 6)
+
+
+/***********************************************************************************
+// Memory-mapped peripherals
+************************************************************************************/
+
+/*// SP810 Controller
+#undef SP810_CTRL_BASE
+#define SP810_CTRL_BASE                         0x1C020000
+
+// PL111 Colour LCD Controller
+#define PL111_CLCD_SITE                         ARM_VE_MOTHERBOARD_SITE
+#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID  1
+#define PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID  1
+
+// VRAM offset for the PL111 Colour LCD Controller on the motherboard
+#define VRAM_MOTHERBOARD_BASE                     (ARM_VE_SMB_PERIPH_BASE   + 0x00000)*/
+
+#endif
diff --git a/Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h b/Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h
new file mode 100644
index 000000000000..d856b6daa1d7
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/Platform/RTSM/ArmPlatform.h
@@ -0,0 +1,79 @@
+/** @file
+*  Header defining Versatile Express constants (Base addresses, sizes, flags)
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __ARM_VEXPRESS_H__
+#define __ARM_VEXPRESS_H__
+
+#include <VExpressMotherBoard.h>
+
+/***********************************************************************************
+// Platform Memory Map
+************************************************************************************/
+
+// Can be NOR0, NOR1, DRAM
+#define ARM_VE_REMAP_BASE                       0x00000000
+#define ARM_VE_REMAP_SZ                         SIZE_64MB
+
+// Motherboard Peripheral and On-chip peripheral
+#define ARM_VE_BOARD_PERIPH_BASE                0x1C010000
+
+// NOR Flash 1
+// There is typo in the reference manual for the Base address of NOR Flash 1
+#define ARM_VE_SMB_NOR0_BASE                    0x08000000
+#define ARM_VE_SMB_NOR0_SZ                      SIZE_64MB
+// NOR Flash 2
+#define ARM_VE_SMB_NOR1_BASE                    0x0C000000
+#define ARM_VE_SMB_NOR1_SZ                      SIZE_64MB
+// SRAM
+#define ARM_VE_SMB_SRAM_BASE                    0x2E000000
+#define ARM_VE_SMB_SRAM_SZ                      SIZE_64KB
+// USB, Ethernet, VRAM
+#define ARM_VE_SMB_PERIPH_BASE                  0x18800000
+#define ARM_VE_SMB_PERIPH_SZ                    (SIZE_64MB - SIZE_8MB)
+
+#define PL111_CLCD_VRAM_MOTHERBOARD_BASE        0x18000000
+#define PL111_CLCD_VRAM_MOTHERBOARD_SIZE        0x800000
+
+// DRAM
+#define ARM_VE_DRAM_BASE                        PcdGet64 (PcdSystemMemoryBase)
+#define ARM_VE_DRAM_SZ                          PcdGet64 (PcdSystemMemorySize)
+
+// This can be any value since we only support motherboard PL111
+#define LCD_VRAM_CORE_TILE_BASE                 0x00000000
+
+// On-chip peripherals (Snoop Control Unit etc...)
+#define ARM_VE_ON_CHIP_PERIPH_BASE              0x2C000000
+// Note: The TRM says not all the peripherals are implemented
+#define ARM_VE_ON_CHIP_PERIPH_SZ                SIZE_256MB
+
+
+// External AXI between daughterboards (Logic Tile)
+#define ARM_VE_EXT_AXI_BASE                     0x2E010000 // Not modelled
+#define ARM_VE_EXT_AXI_SZ                       0x20000000  /* 512 MB */
+
+/***********************************************************************************
+// Memory-mapped peripherals
+************************************************************************************/
+
+// SP810 Controller
+#undef SP810_CTRL_BASE
+#define SP810_CTRL_BASE                         0x1C020000
+
+// PL111 Colour LCD Controller
+#define PL111_CLCD_SITE                         ARM_VE_MOTHERBOARD_SITE
+#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID  1
+#define PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID  1
+
+#endif
diff --git a/Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h b/Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h
new file mode 100644
index 000000000000..38691c35828b
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Include/VExpressMotherBoard.h
@@ -0,0 +1,140 @@
+/** @file
+*  Header defining Versatile Express constants (Base addresses, sizes, flags)
+*
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __VEXPRESSMOTHERBOARD_H_
+#define __VEXPRESSMOTHERBOARD_H_
+
+#include <ArmPlatform.h>
+
+/***********************************************************************************
+// Motherboard memory-mapped peripherals
+************************************************************************************/
+
+// Define MotherBoard SYS flags offsets (from ARM_VE_BOARD_PERIPH_BASE)
+#define ARM_VE_SYS_ID_REG                         (ARM_VE_BOARD_PERIPH_BASE + 0x00000)
+#define ARM_VE_SYS_SW_REG                         (ARM_VE_BOARD_PERIPH_BASE + 0x00004)
+#define ARM_VE_SYS_LED_REG                        (ARM_VE_BOARD_PERIPH_BASE + 0x00008)
+#define ARM_VE_SYS_FLAGS_REG                      (ARM_VE_BOARD_PERIPH_BASE + 0x00030)
+#define ARM_VE_SYS_FLAGS_SET_REG                  (ARM_VE_BOARD_PERIPH_BASE + 0x00030)
+#define ARM_VE_SYS_FLAGS_CLR_REG                  (ARM_VE_BOARD_PERIPH_BASE + 0x00034)
+#define ARM_VE_SYS_FLAGS_NV_REG                   (ARM_VE_BOARD_PERIPH_BASE + 0x00038)
+#define ARM_VE_SYS_FLAGS_NV_SET_REG               (ARM_VE_BOARD_PERIPH_BASE + 0x00038)
+#define ARM_VE_SYS_FLAGS_NV_CLR_REG               (ARM_VE_BOARD_PERIPH_BASE + 0x0003C)
+#define ARM_VE_SYS_FLASH                          (ARM_VE_BOARD_PERIPH_BASE + 0x0004C)
+#define ARM_VE_SYS_CFGSWR_REG                     (ARM_VE_BOARD_PERIPH_BASE + 0x00058)
+#define ARM_VE_SYS_MISC                           (ARM_VE_BOARD_PERIPH_BASE + 0x00060)
+#define ARM_VE_SYS_PROCID0_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x00084)
+#define ARM_VE_SYS_PROCID1_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x00088)
+#define ARM_VE_SYS_CFGDATA_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x000A0)
+#define ARM_VE_SYS_CFGCTRL_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x000A4)
+#define ARM_VE_SYS_CFGSTAT_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x000A8)
+
+// SP810 Controller
+#ifndef SP810_CTRL_BASE
+#define SP810_CTRL_BASE                           (ARM_VE_BOARD_PERIPH_BASE + 0x01000)
+#endif
+
+// PL111 Colour LCD Controller - motherboard
+#define PL111_CLCD_MOTHERBOARD_BASE               (ARM_VE_BOARD_PERIPH_BASE + 0x1F000)
+#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID  1
+
+// VRAM offset for the PL111 Colour LCD Controller on the motherboard
+#define VRAM_MOTHERBOARD_BASE                     (ARM_VE_SMB_PERIPH_BASE   + 0x00000)
+
+#define ARM_VE_SYS_PROC_ID_HBI                    0xFFF
+#define ARM_VE_SYS_PROC_ID_MASK                   (UINT32)(0xFFU << 24)
+#define ARM_VE_SYS_PROC_ID_UNSUPPORTED            (UINT32)(0xFFU << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A9              (UINT32)(0x0CU << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A5              (UINT32)(0x12U << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A15             (UINT32)(0x14U << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A7              (UINT32)(0x18U << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A12             (UINT32)(0x1CU << 24)
+
+// Boot Master Select:
+// 0 = Site 1 boot master
+// 1 = Site 2 boot master
+#define ARM_VE_SYS_MISC_MASTERSITE                (1 << 14)
+//
+// Sites where the peripheral is fitted
+//
+#define ARM_VE_UNSUPPORTED                        ~0
+#define ARM_VE_MOTHERBOARD_SITE                   0
+#define ARM_VE_DAUGHTERBOARD_1_SITE               1
+#define ARM_VE_DAUGHTERBOARD_2_SITE               2
+
+#define VIRTUAL_SYS_CFG(site,func)                (((site) << 24) | (func))
+
+//
+// System Configuration Control Functions
+//
+#define SYS_CFG_OSC                               1
+#define SYS_CFG_VOLT                              2
+#define SYS_CFG_AMP                               3
+#define SYS_CFG_TEMP                              4
+#define SYS_CFG_RESET                             5
+#define SYS_CFG_SCC                               6
+#define SYS_CFG_MUXFPGA                           7
+#define SYS_CFG_SHUTDOWN                          8
+#define SYS_CFG_REBOOT                            9
+#define SYS_CFG_DVIMODE                           11
+#define SYS_CFG_POWER                             12
+// Oscillator for Site 1
+#define SYS_CFG_OSC_SITE1                         VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_1_SITE,SYS_CFG_OSC)
+// Oscillator for Site 2
+#define SYS_CFG_OSC_SITE2                         VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_2_SITE,SYS_CFG_OSC)
+// Can not access the battery backed-up hardware clock on the Versatile Express motherboard
+#define SYS_CFG_RTC                               VIRTUAL_SYS_CFG(ARM_VE_UNSUPPORTED,1)
+
+//
+// System ID
+//
+// All RTSM VE models have the same System ID : 0x225F500
+//
+// FVP models have a different System ID.
+// Default Base model System ID : 0x00201100
+// [31:28] Rev     - Board revision:          0x0     = Rev A
+// [27:16] HBI     - HBI board number in BCD: 0x020   = v8 Base Platform
+// [15:12] Variant - Build variant of board:  0x1     = Variant B. (GIC 64k map)
+// [11:8]  Plat    - Platform type:           0x1     = Model
+// [7:0]   FPGA    - FPGA build, BCD coded:   0x00
+//
+//HBI = 010 = Foundation Model
+//HBI = 020 = Base Platform
+//
+// And specifically, the GIC register banks start at the following
+// addresses:
+//              Variant = 0             Variant = 1
+//GICD          0x2c001000              0x2f000000
+//GICC          0x2c002000              0x2c000000
+//GICH          0x2c004000              0x2c010000
+//GICV          0x2c006000              0x2c020000
+
+#define ARM_FVP_BASE_BOARD_SYS_ID       (0x00200100)
+#define ARM_FVP_FOUNDATION_BOARD_SYS_ID (0x00100100)
+
+#define ARM_FVP_SYS_ID_REV_MASK        (UINT32)(0xFUL   << 28)
+#define ARM_FVP_SYS_ID_HBI_MASK        (UINT32)(0xFFFUL << 16)
+#define ARM_FVP_SYS_ID_VARIANT_MASK    (UINT32)(0xFUL   << 12)
+#define ARM_FVP_SYS_ID_PLAT_MASK       (UINT32)(0xFUL   << 8 )
+#define ARM_FVP_SYS_ID_FPGA_MASK       (UINT32)(0xFFUL  << 0 )
+#define ARM_FVP_GIC_VE_MMAP            0x0
+#define ARM_FVP_GIC_BASE_MMAP          (UINT32)(1 << 12)
+
+// The default SYS_IDs. These can be changed when starting the model.
+#define ARM_RTSM_SYS_ID                (0x225F500)
+#define ARM_FVP_BASE_SYS_ID            (ARM_FVP_BASE_BOARD_SYS_ID | ARM_FVP_GIC_BASE_MMAP)
+#define ARM_FVP_FOUNDATION_SYS_ID      (ARM_FVP_FOUNDATION_BOARD_SYS_ID | ARM_FVP_GIC_BASE_MMAP)
+
+#endif /* VEXPRESSMOTHERBOARD_H_ */
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
new file mode 100644
index 000000000000..9e81b1c1cc16
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
@@ -0,0 +1,54 @@
+#/* @file
+#
+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = CTA15A7ArmVExpressLib
+  FILE_GUID                      = b98a6cb7-d472-4128-ad62-a7347f85ce13
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  MemoryAllocationLib
+  SerialPortLib
+
+[Sources.common]
+  CTA15-A7.c
+  CTA15-A7Mem.c
+  CTA15-A7Helper.asm | RVCT
+  CTA15-A7Helper.S   | GCC
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c
new file mode 100644
index 000000000000..93f4d82f1988
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7.c
@@ -0,0 +1,195 @@
+/** @file
+*
+*  Copyright (c) 2012, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include <ArmPlatform.h>
+
+ARM_CORE_INFO mVersatileExpressCTA15A7InfoTable[] = {
+  {
+    // Cluster 0, Core 0
+    0x0, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR0,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR0,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR0,
+    (UINT64)0
+  },
+  {
+    // Cluster 0, Core 1
+    0x0, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR1,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR1,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR1,
+    (UINT64)0
+  },
+#ifndef ARM_BIGLITTLE_TC2
+  {
+    // Cluster 0, Core 2
+    0x0, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR2,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR2,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR2,
+    (UINT64)0
+  },
+  {
+    // Cluster 0, Core 3
+    0x0, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR3,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR3,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A15_BX_ADDR3,
+    (UINT64)0
+  },
+#endif
+  {
+    // Cluster 1, Core 0
+    0x1, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR0,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR0,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR0,
+    (UINT64)0
+  },
+  {
+    // Cluster 1, Core 1
+    0x1, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR1,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR1,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR1,
+    (UINT64)0
+  },
+  {
+    // Cluster 1, Core 2
+    0x1, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR2,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR2,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR2,
+    (UINT64)0
+  }
+#ifndef ARM_BIGLITTLE_TC2
+  ,{
+    // Cluster 1, Core 3
+    0x1, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR3,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR3,
+    (EFI_PHYSICAL_ADDRESS)ARM_CTA15A7_SPC_A7_BX_ADDR3,
+    (UINT64)0
+  }
+#endif
+};
+
+/**
+  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
+  )
+{
+  if (MmioRead32(ARM_CTA15A7_SCC_SYSINFO) & ARM_CTA15A7_SCC_SYSINFO_UEFI_RESTORE_DEFAULT_NORFLASH) {
+    return BOOT_WITH_DEFAULT_SETTINGS;
+  } else {
+    return BOOT_WITH_FULL_CONFIGURATION;
+  }
+}
+
+/**
+  Initialize controllers that must setup in the normal world
+
+  This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+  in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  if (!ArmPlatformIsPrimaryCore (MpId)) {
+    return RETURN_SUCCESS;
+  }
+
+  // Nothing to do here
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Initialize the system (or sometimes called permanent) memory
+
+  This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+  VOID
+  )
+{
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN                   *CoreCount,
+  OUT ARM_CORE_INFO           **ArmCoreTable
+  )
+{
+  // Only support one cluster
+  *CoreCount    = sizeof(mVersatileExpressCTA15A7InfoTable) / sizeof(ARM_CORE_INFO);
+  *ArmCoreTable = mVersatileExpressCTA15A7InfoTable;
+  return EFI_SUCCESS;
+}
+
+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/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S
new file mode 100644
index 000000000000..3719a5ace604
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.S
@@ -0,0 +1,81 @@
+//
+//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//
+//  This program and the accompanying materials
+//  are licensed and made available under the terms and conditions of the BSD License
+//  which accompanies this distribution.  The full text of the license may be found at
+//  http://opensource.org/licenses/bsd-license.php
+//
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <AsmMacroIoLib.h>
+#include <Library/ArmLib.h>
+
+#include <ArmPlatform.h>
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  bx    lr
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformGetCorePosition)
+  and   r1, r0, #ARM_CORE_MASK
+  and   r0, r0, #ARM_CLUSTER_MASK
+  add   r0, r1, r0, LSR #7
+  bx    lr
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+  // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48
+  // with cpu_id[0:3] and cluster_id[4:7]
+  MOV32 (r1, ARM_CTA15A7_SCC_CFGREG48)
+  ldr   r1, [r1]
+  lsr   r1, #24
+
+  // Shift the SCC value to get the cluster ID at the offset #8
+  lsl   r2, r1, #4
+  and   r2, r2, #0xF00
+
+  // Keep only the cpu ID from the original SCC
+  and   r1, r1, #0x0F
+  // Add the Cluster ID to the Cpu ID
+  orr   r1, r1, r2
+
+  // Keep the Cluster ID and Core ID from the MPID
+  MOV32 (r2, ARM_CLUSTER_MASK | ARM_CORE_MASK)
+  and   r0, r0, r2
+
+  // Compare mpid and boot cpu from ARM_SCC_CFGREG48
+  cmp   r0, r1
+  moveq r0, #1
+  movne r0, #0
+  bx    lr
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48
+  // with cpu_id[0:3] and cluster_id[4:7]
+  MOV32 (r0, ARM_CTA15A7_SCC_CFGREG48)
+  ldr   r0, [r0]
+  lsr   r0, #24
+
+  // Shift the SCC value to get the cluster ID at the offset #8
+  lsl   r1, r0, #4
+  and   r1, r1, #0xF00
+
+  // Keep only the cpu ID from the original SCC
+  and   r0, r0, #0x0F
+  // Add the Cluster ID to the Cpu ID
+  orr   r0, r0, r1
+  bx    lr
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm
new file mode 100644
index 000000000000..c035843da078
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Helper.asm
@@ -0,0 +1,96 @@
+//
+//  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+//
+//  This program and the accompanying materials
+//  are licensed and made available under the terms and conditions of the BSD License
+//  which accompanies this distribution.  The full text of the license may be found at
+//  http://opensource.org/licenses/bsd-license.php
+//
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <Library/ArmLib.h>
+
+#include <ArmPlatform.h>
+
+  INCLUDE AsmMacroIoLib.inc
+
+  EXPORT  ArmPlatformPeiBootAction
+  EXPORT  ArmPlatformGetCorePosition
+  EXPORT  ArmPlatformIsPrimaryCore
+  EXPORT  ArmPlatformGetPrimaryCoreMpId
+
+  PRESERVE8
+  AREA    CTA15A7Helper, CODE, READONLY
+
+ArmPlatformPeiBootAction FUNCTION
+  bx    lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ArmPlatformGetCorePosition FUNCTION
+  and   r1, r0, #ARM_CORE_MASK
+  and   r0, r0, #ARM_CLUSTER_MASK
+  add   r0, r1, r0, LSR #7
+  bx    lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ArmPlatformIsPrimaryCore FUNCTION
+  // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48
+  // with cpu_id[0:3] and cluster_id[4:7]
+  mov32 r1, ARM_CTA15A7_SCC_CFGREG48
+  ldr   r1, [r1]
+  lsr   r1, #24
+
+  // Shift the SCC value to get the cluster ID at the offset #8
+  lsl   r2, r1, #4
+  and   r2, r2, #0xF00
+
+  // Keep only the cpu ID from the original SCC
+  and   r1, r1, #0x0F
+  // Add the Cluster ID to the Cpu ID
+  orr   r1, r1, r2
+
+  // Keep the Cluster ID and Core ID from the MPID
+  mov32 r2, ARM_CLUSTER_MASK :OR: ARM_CORE_MASK
+  and   r0, r0, r2
+
+  // Compare mpid and boot cpu from ARM_SCC_CFGREG48
+  cmp   r0, r1
+  moveq r0, #1
+  movne r0, #0
+  bx    lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ArmPlatformGetPrimaryCoreMpId FUNCTION
+  // Extract cpu_id and cluster_id from ARM_SCC_CFGREG48
+  // with cpu_id[0:3] and cluster_id[4:7]
+  mov32 r0, ARM_CTA15A7_SCC_CFGREG48
+  ldr   r0, [r0]
+  lsr   r0, #24
+
+  // Shift the SCC value to get the cluster ID at the offset #8
+  lsl   r1, r0, #4
+  and   r1, r1, #0xF00
+
+  // Keep only the cpu ID from the original SCC
+  and   r0, r0, #0x0F
+  // Add the Cluster ID to the Cpu ID
+  orr   r0, r0, r1
+  bx    lr
+  ENDFUNC
+
+  END
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c
new file mode 100644
index 000000000000..4403cbacb881
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibCTA15-A7/CTA15-A7Mem.c
@@ -0,0 +1,182 @@
+/** @file
+*
+*  Copyright (c) 2012, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+#include <ArmPlatform.h>
+
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 14
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+                                    Virtual Memory mapping. This array must be ended by a zero-filled
+                                    entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
+  UINTN                         Index = 0;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+    return;
+  }
+
+  if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
+    CacheAttributes = DDR_ATTRIBUTES_CACHED;
+  } else {
+    CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+  }
+
+#ifdef ARM_BIGLITTLE_TC2
+  // Secure NOR0 Flash
+  VirtualMemoryTable[Index].PhysicalBase    = ARM_VE_SEC_NOR0_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SEC_NOR0_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_SEC_NOR0_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  // Secure RAM
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SEC_RAM0_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SEC_RAM0_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_SEC_RAM0_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+#endif
+
+  // SMB CS0 - NOR0 Flash
+  VirtualMemoryTable[Index].PhysicalBase    = ARM_VE_SMB_NOR0_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_NOR0_BASE;
+  VirtualMemoryTable[Index].Length          = SIZE_256KB * 255;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  // Environment Variables region
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255);
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255);
+  VirtualMemoryTable[Index].Length          = SIZE_64KB * 4;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // SMB CS1 or CS4 - NOR1 Flash
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_NOR1_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_NOR1_BASE;
+  VirtualMemoryTable[Index].Length          = SIZE_256KB * 255;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  // Environment Variables region
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255);
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_NOR1_BASE + (SIZE_256KB * 255);
+  VirtualMemoryTable[Index].Length          = SIZE_64KB * 4;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // SMB CS3 or CS1 - PSRAM
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_SRAM_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_SRAM_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_SMB_SRAM_SZ;
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // Motherboard peripherals
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_SMB_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_SMB_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_SMB_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+#ifdef ARM_BIGLITTLE_TC2
+  // Non-secure ROM
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_TC2_NON_SECURE_ROM_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_TC2_NON_SECURE_ROM_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_TC2_NON_SECURE_ROM_SZ;
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+#endif
+
+  // OnChip peripherals
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_ONCHIP_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_ONCHIP_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_ONCHIP_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // SCC Region
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_CTA15A7_SCC_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_CTA15A7_SCC_BASE;
+  VirtualMemoryTable[Index].Length          = SIZE_64KB;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+#ifdef ARM_BIGLITTLE_TC2
+  // TC2 OnChip non-secure SRAM
+  VirtualMemoryTable[++Index].PhysicalBase  = ARM_VE_TC2_NON_SECURE_SRAM_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = ARM_VE_TC2_NON_SECURE_SRAM_BASE;
+  VirtualMemoryTable[Index].Length          = ARM_VE_TC2_NON_SECURE_SRAM_SZ;
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+#endif
+
+#ifndef ARM_BIGLITTLE_TC2
+  // Workaround for SRAM bug in RTSM
+  if (PcdGet64 (PcdSystemMemoryBase) != 0x80000000) {
+    VirtualMemoryTable[++Index].PhysicalBase  = 0x80000000;
+    VirtualMemoryTable[Index].VirtualBase     = 0x80000000;
+    VirtualMemoryTable[Index].Length          = PcdGet64 (PcdSystemMemoryBase) - 0x80000000;
+    VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+  }
+#endif
+
+  // DDR
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length          = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // Detect if it is a 1GB or 2GB Test Chip
+  //   [16:19]: 0=1GB TC2, 1=2GB TC2
+  if (MmioRead32(ARM_VE_SYS_PROCID0_REG) & (0xF << 16)) {
+    DEBUG((EFI_D_ERROR,"Info: 2GB Test Chip 2 detected.\n"));
+    BuildResourceDescriptorHob (
+        EFI_RESOURCE_SYSTEM_MEMORY,
+        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,
+        PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize),
+        SIZE_1GB
+    );
+
+    // Map the additional 1GB into the MMU
+    VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize);
+    VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize);
+    VirtualMemoryTable[Index].Length          = SIZE_1GB;
+    VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+  }
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase  = 0;
+  VirtualMemoryTable[Index].VirtualBase     = 0;
+  VirtualMemoryTable[Index].Length          = 0;
+  VirtualMemoryTable[Index].Attributes      = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S
new file mode 100644
index 000000000000..db6d83c3cce9
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/AArch64/RTSMHelper.S
@@ -0,0 +1,61 @@
+#
+#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  MOV32  (w0, FixedPcdGet32 (PcdArmPrimaryCore))
+  ret
+
+# IN None
+# OUT x0 = number of cores present in the system
+ASM_FUNC(ArmGetCpuCountPerCluster)
+  MOV32  (w0, FixedPcdGet32 (PcdCoreCount))
+  ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+  MOV32  (w1, FixedPcdGet32 (PcdArmPrimaryCoreMask))
+  and   x0, x0, x1
+  MOV32  (w1, FixedPcdGet32 (PcdArmPrimaryCore))
+  cmp   w0, w1
+  b.ne  1f
+  mov   x0, #1
+  ret
+1:
+  mov   x0, #0
+  ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_FUNC(ArmPlatformGetCorePosition)
+  and   x1, x0, #ARM_CORE_MASK
+  and   x0, x0, #ARM_CLUSTER_MASK
+  add   x0, x1, x0, LSR #6
+  ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S
new file mode 100644
index 000000000000..35743b08dc88
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.S
@@ -0,0 +1,97 @@
+#
+#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+
+#include <AsmMacroIoLib.h>
+#include <Library/ArmLib.h>
+
+#include <Chipset/ArmCortexA9.h>
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  bx    lr
+
+# IN None
+# OUT r0 = SCU Base Address
+ASM_FUNC(ArmGetScuBaseAddress)
+  # Read Configuration Base Address Register. ArmCBar cannot be called to get
+  # the Configuration BAR as a stack is not necessary setup. The SCU is at the
+  # offset 0x0000 from the Private Memory Region.
+  mrc   p15, 4, r0, c15, c0, 0
+  bx    lr
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  MOV32  (r0, FixedPcdGet32 (PcdArmPrimaryCore))
+  bx    lr
+
+# IN None
+# OUT r0 = number of cores present in the system
+ASM_FUNC(ArmGetCpuCountPerCluster)
+  stmfd SP!, {r1-r2}
+
+  # Read CP15 MIDR
+  mrc   p15, 0, r1, c0, c0, 0
+
+  # Check if the CPU is A15
+  mov   r1, r1, LSR #4
+  MOV32 (r0, ARM_CPU_TYPE_MASK)
+  and   r1, r1, r0
+
+  MOV32 (r0, ARM_CPU_TYPE_A15)
+  cmp   r1, r0
+  beq   _Read_cp15_reg
+
+_CPU_is_not_A15:
+  mov   r2, lr                           @ Save link register
+  bl    ArmGetScuBaseAddress             @ Read SCU Base Address
+  mov   lr, r2                           @ Restore link register val
+  ldr   r0, [r0, #A9_SCU_CONFIG_OFFSET]     @ Read SCU Config reg to get CPU count
+  b     _Return
+
+_Read_cp15_reg:
+  mrc   p15, 1, r0, c9, c0, 2            @ Read C9 register of CP15 to get CPU count
+  lsr   r0, #24
+
+_Return:
+  and   r0, r0, #3
+  # Add '1' to the number of CPU on the Cluster
+  add   r0, r0, #1
+  ldmfd SP!, {r1-r2}
+  bx lr
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+  MOV32  (r1, FixedPcdGet32 (PcdArmPrimaryCoreMask))
+  and   r0, r0, r1
+  MOV32  (r1, FixedPcdGet32 (PcdArmPrimaryCore))
+  cmp   r0, r1
+  moveq r0, #1
+  movne r0, #0
+  bx    lr
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformGetCorePosition)
+  and   r1, r0, #ARM_CORE_MASK
+  and   r0, r0, #ARM_CLUSTER_MASK
+  add   r0, r1, r0, LSR #7
+  bx    lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm
new file mode 100644
index 000000000000..66068e6595db
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/Arm/RTSMHelper.asm
@@ -0,0 +1,118 @@
+//
+//  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+//
+//  This program and the accompanying materials
+//  are licensed and made available under the terms and conditions of the BSD License
+//  which accompanies this distribution.  The full text of the license may be found at
+//  http://opensource.org/licenses/bsd-license.php
+//
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+
+#include <Chipset/ArmCortexA9.h>
+
+#include <AutoGen.h>
+
+  INCLUDE AsmMacroIoLib.inc
+
+  EXPORT    ArmPlatformPeiBootAction
+  EXPORT    ArmGetCpuCountPerCluster
+  EXPORT    ArmPlatformIsPrimaryCore
+  EXPORT    ArmPlatformGetPrimaryCoreMpId
+  EXPORT    ArmPlatformGetCorePosition
+
+  AREA RTSMHelper, CODE, READONLY
+
+ArmPlatformPeiBootAction FUNCTION
+  bx    lr
+  ENDFUNC
+
+// IN None
+// OUT r0 = SCU Base Address
+ArmGetScuBaseAddress FUNCTION
+  // Read Configuration Base Address Register. ArmCBar cannot be called to get
+  // the Configuration BAR as a stack is not necessary setup. The SCU is at the
+  // offset 0x0000 from the Private Memory Region.
+  mrc   p15, 4, r0, c15, c0, 0
+  bx  lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ArmPlatformGetPrimaryCoreMpId FUNCTION
+  mov32 r0, FixedPcdGet32(PcdArmPrimaryCore)
+  bx    lr
+  ENDFUNC
+
+// IN None
+// OUT r0 = number of cores present in the system
+ArmGetCpuCountPerCluster FUNCTION
+  stmfd SP!, {r1-r2}
+
+  // Read CP15 MIDR
+  mrc   p15, 0, r1, c0, c0, 0
+
+  // Check if the CPU is A15
+  mov   r1, r1, LSR #4
+  mov   r0, #ARM_CPU_TYPE_MASK
+  and   r1, r1, r0
+
+  mov   r0, #ARM_CPU_TYPE_A15
+  cmp   r1, r0
+  beq   _Read_cp15_reg
+
+_CPU_is_not_A15
+  mov   r2, lr                              ; Save link register
+  bl    ArmGetScuBaseAddress                ; Read SCU Base Address
+  mov   lr, r2                              ; Restore link register val
+  ldr   r0, [r0, #A9_SCU_CONFIG_OFFSET]     ; Read SCU Config reg to get CPU count
+  b     _Return
+
+_Read_cp15_reg
+  mrc   p15, 1, r0, c9, c0, 2            ; Read C9 register of CP15 to get CPU count
+  lsr   r0, #24
+
+
+_Return
+  and   r0, r0, #3
+  // Add '1' to the number of CPU on the Cluster
+  add   r0, r0, #1
+  ldmfd SP!, {r1-r2}
+  bx lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ArmPlatformIsPrimaryCore FUNCTION
+  mov32 r1, FixedPcdGet32(PcdArmPrimaryCoreMask)
+  and   r0, r0, r1
+  mov32 r1, FixedPcdGet32(PcdArmPrimaryCore)
+  ldr   r1, [r1]
+  cmp   r0, r1
+  moveq r0, #1
+  movne r0, #0
+  bx    lr
+  ENDFUNC
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ArmPlatformGetCorePosition FUNCTION
+  and   r1, r0, #ARM_CORE_MASK
+  and   r0, r0, #ARM_CLUSTER_MASK
+  add   r0, r1, r0, LSR #7
+  bx    lr
+  ENDFUNC
+
+  END
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
new file mode 100644
index 000000000000..2322ee6a2cc5
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
@@ -0,0 +1,63 @@
+#/* @file
+#  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RTSMArmVExpressLib
+  FILE_GUID                      = b98a6cb7-d472-4128-ad62-a7347f85ce13
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  MemoryAllocationLib
+  SerialPortLib
+  HobLib
+
+[Sources.common]
+  RTSM.c
+  RTSMMem.c
+
+[Sources.ARM]
+  Arm/RTSMHelper.asm    | RVCT
+  Arm/RTSMHelper.S      | GCC
+
+[Sources.AARCH64]
+  AArch64/RTSMHelper.S
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+  gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
new file mode 100644
index 000000000000..e659f44ad232
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
@@ -0,0 +1,59 @@
+#/* @file
+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RTSMArmVExpressLibSec
+  FILE_GUID                      = a79eed97-4b98-4974-9690-37b32d6a5b56
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  SerialPortLib
+
+[Sources.common]
+  RTSM.c
+
+[Sources.ARM]
+  Arm/RTSMHelper.asm    | RVCT
+  Arm/RTSMHelper.S      | GCC
+
+[Sources.AARCH64]
+  AArch64/RTSMHelper.S
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+  gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c
new file mode 100644
index 000000000000..11dd7ff1bfb0
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c
@@ -0,0 +1,209 @@
+/** @file
+*
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include <ArmPlatform.h>
+
+/**
+  Return the core per cluster. The method may differ per core type
+
+  This function might be called from assembler before any stack is set.
+
+  @return   Return the core count per cluster
+
+**/
+UINTN
+ArmGetCpuCountPerCluster (
+  VOID
+  );
+
+ARM_CORE_INFO mVersatileExpressMpCoreInfoTable[] = {
+  {
+    // Cluster 0, Core 0
+    0x0, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 1
+    0x0, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 2
+    0x0, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 3
+    0x0, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 0
+    0x1, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 1
+    0x1, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 2
+    0x1, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 3
+    0x1, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+    (UINT64)0xFFFFFFFF
+  }
+};
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+  @return   Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  Initialize controllers that must setup in the normal world
+
+  This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+  in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  if (!ArmPlatformIsPrimaryCore (MpId)) {
+    return RETURN_SUCCESS;
+  }
+
+  // Disable memory remapping and return to normal mapping
+  MmioOr32 (SP810_CTRL_BASE, BIT8);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Initialize the system (or sometimes called permanent) memory
+
+  This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+  VOID
+  )
+{
+  // Nothing to do here
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN                   *CoreCount,
+  OUT ARM_CORE_INFO           **ArmCoreTable
+  )
+{
+  UINT32   ProcType;
+
+  ProcType = MmioRead32 (ARM_VE_SYS_PROCID0_REG) & ARM_VE_SYS_PROC_ID_MASK;
+  if ((ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A9) || (ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A15)) {
+    // Only support one cluster on all but ARMv8 FVP platform. FVP still uses CortexA9 ID.
+    *CoreCount    = ArmGetCpuCountPerCluster ();
+    *ArmCoreTable = mVersatileExpressMpCoreInfoTable;
+    return EFI_SUCCESS;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+}
+
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR      gPlatformPpiTable[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gArmMpCoreInfoPpiGuid,
+    &mMpCoreInfoPpi
+  }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                   *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
+  )
+{
+  *PpiListSize = sizeof(gPlatformPpiTable);
+  *PpiList = gPlatformPpiTable;
+}
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c
new file mode 100644
index 000000000000..6379e81751fc
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c
@@ -0,0 +1,161 @@
+/** @file
+*
+*  Copyright (c) 2011-2016, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <ArmPlatform.h>
+
+// Number of Virtual Memory Map Descriptors
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          9
+
+// 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;
+  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
+  UINTN                         Index = 0;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  UINT32                        SysId;
+  BOOLEAN                       HasSparseMemory;
+  EFI_VIRTUAL_ADDRESS           SparseMemoryBase;
+  UINT64                        SparseMemorySize;
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  // The FVP model has Sparse memory
+  SysId = MmioRead32 (ARM_VE_SYS_ID_REG);
+  if (SysId != ARM_RTSM_SYS_ID) {
+    HasSparseMemory = TRUE;
+
+    ResourceAttributes =
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED;
+
+    // Declared the additional DRAM from 2GB to 4GB
+    SparseMemoryBase = 0x0880000000;
+    SparseMemorySize = SIZE_2GB;
+
+    BuildResourceDescriptorHob (
+        EFI_RESOURCE_SYSTEM_MEMORY,
+        ResourceAttributes,
+        SparseMemoryBase,
+        SparseMemorySize);
+  } else {
+    HasSparseMemory = FALSE;
+    SparseMemoryBase = 0x0;
+    SparseMemorySize = 0x0;
+  }
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)
+    AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR)
+                                      * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+    return;
+  }
+
+  CacheAttributes = (FeaturePcdGet(PcdCacheEnable))
+                    ? DDR_ATTRIBUTES_CACHED
+                    : DDR_ATTRIBUTES_UNCACHED;
+
+  // ReMap (Either NOR Flash or DRAM)
+  VirtualMemoryTable[Index].PhysicalBase = ARM_VE_REMAP_BASE;
+  VirtualMemoryTable[Index].VirtualBase = ARM_VE_REMAP_BASE;
+  VirtualMemoryTable[Index].Length = ARM_VE_REMAP_SZ;
+  VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+  // DDR
+  VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_DRAM_BASE;
+  VirtualMemoryTable[Index].VirtualBase = ARM_VE_DRAM_BASE;
+  VirtualMemoryTable[Index].Length = ARM_VE_DRAM_SZ;
+  VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+  // CPU peripherals. TRM. Manual says not all of them are implemented.
+  VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_ON_CHIP_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase = ARM_VE_ON_CHIP_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length = ARM_VE_ON_CHIP_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // SMB CS0-CS1 - NOR Flash 1 & 2
+  VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE;
+  VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE;
+  VirtualMemoryTable[Index].Length = ARM_VE_SMB_NOR0_SZ + ARM_VE_SMB_NOR1_SZ;
+  VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+  // SMB CS2 - SRAM
+  VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_SRAM_BASE;
+  VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_SRAM_BASE;
+  VirtualMemoryTable[Index].Length = ARM_VE_SMB_SRAM_SZ;
+  VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+  // Peripheral CS2 and CS3
+  VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length = 2 * ARM_VE_SMB_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // VRAM
+  VirtualMemoryTable[++Index].PhysicalBase = PL111_CLCD_VRAM_MOTHERBOARD_BASE;
+  VirtualMemoryTable[Index].VirtualBase = PL111_CLCD_VRAM_MOTHERBOARD_BASE;
+  VirtualMemoryTable[Index].Length = PL111_CLCD_VRAM_MOTHERBOARD_SIZE;
+  //
+  // Map the VRAM region as Normal Non-Cacheable memory and not device memory,
+  // so that we can use the accelerated string routines that may use unaligned
+  // accesses or DC ZVA instructions. The enum identifier is slightly awkward
+  // here, but it maps to a memory type that allows buffering and reordering.
+  //
+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
+
+  // Map sparse memory region if present
+  if (HasSparseMemory) {
+    VirtualMemoryTable[++Index].PhysicalBase = SparseMemoryBase;
+    VirtualMemoryTable[Index].VirtualBase = SparseMemoryBase;
+    VirtualMemoryTable[Index].Length = SparseMemorySize;
+    VirtualMemoryTable[Index].Attributes = CacheAttributes;
+  }
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase = 0;
+  VirtualMemoryTable[Index].VirtualBase = 0;
+  VirtualMemoryTable[Index].Length = 0;
+  VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT (Index < MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c
new file mode 100644
index 000000000000..6dfbacd11762
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfig.c
@@ -0,0 +1,273 @@
+/** @file  ArmVExpressSysConfig.c
+
+  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/ArmPlatformSysConfigLib.h>
+#include <ArmPlatform.h>
+
+//
+// SYS_CFGCTRL Bits
+//
+#define SYS_CFGCTRL_START                 BIT31
+#define SYS_CFGCTRL_READ                  (0 << 30)
+#define SYS_CFGCTRL_WRITE                 (1 << 30)
+#define SYS_CFGCTRL_FUNCTION(fun)         (((fun ) &  0x3F) << 20)
+#define SYS_CFGCTRL_SITE(site)            (((site) &   0x3) << 16)
+#define SYS_CFGCTRL_POSITION(pos)         (((pos ) &   0xF) << 12)
+#define SYS_CFGCTRL_DEVICE(dev)            ((dev ) & 0xFFF)
+
+//
+// SYS_CFGSTAT Bits
+//
+#define SYS_CFGSTAT_ERROR                 BIT1
+#define SYS_CFGSTAT_COMPLETE              BIT0
+
+/****************************************************************************
+ *
+ *  This file makes it easier to access the System Configuration Registers
+ *  in the ARM Versatile Express motherboard.
+ *
+ ****************************************************************************/
+
+RETURN_STATUS
+ArmPlatformSysConfigInitialize (
+  VOID
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+/***************************************
+ * GENERAL FUNCTION: AccessSysCfgRegister
+ * Interacts with
+ *    SYS_CFGSTAT
+ *    SYS_CFGDATA
+ *    SYS_CFGCTRL
+ * for setting and for reading out values
+ ***************************************/
+
+RETURN_STATUS
+AccessSysCfgRegister (
+  IN     UINT32   ReadWrite,
+  IN     UINT32   Function,
+  IN     UINT32   Site,
+  IN     UINT32   Position,
+  IN     UINT32   Device,
+  IN OUT UINT32*  Data
+  )
+{
+  UINT32          SysCfgCtrl;
+
+  // Clear the COMPLETE bit
+  MmioAnd32(ARM_VE_SYS_CFGSTAT_REG, ~SYS_CFGSTAT_COMPLETE);
+
+  // If writing, then set the data value
+  if(ReadWrite == SYS_CFGCTRL_WRITE) {
+    MmioWrite32(ARM_VE_SYS_CFGDATA_REG, *Data);
+  }
+
+  // Set the control value
+  SysCfgCtrl = SYS_CFGCTRL_START | ReadWrite | SYS_CFGCTRL_FUNCTION(Function) | SYS_CFGCTRL_SITE(Site) |
+      SYS_CFGCTRL_POSITION(Position) | SYS_CFGCTRL_DEVICE(Device);
+  MmioWrite32(ARM_VE_SYS_CFGCTRL_REG, SysCfgCtrl);
+
+  // Wait until the COMPLETE bit is set
+  while ((MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_COMPLETE) == 0);
+
+  // Check for errors
+  if(MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_ERROR) {
+    return RETURN_DEVICE_ERROR;
+  }
+
+  // If reading then get the data value
+  if(ReadWrite == SYS_CFGCTRL_READ) {
+    *Data = MmioRead32(ARM_VE_SYS_CFGDATA_REG);
+  }
+
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigGet (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  OUT UINT32*               Value
+  )
+{
+  UINT32          Site;
+  UINT32          Position;
+  UINT32          Device;
+
+  Position = 0;
+  Device = 0;
+
+  // Intercept some functions
+  switch(Function) {
+
+  case SYS_CFG_OSC_SITE1:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_1_SITE;
+    break;
+
+  case SYS_CFG_OSC_SITE2:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_2_SITE;
+    break;
+
+  case SYS_CFG_MUXFPGA:
+    Site = *Value;
+    break;
+
+  case SYS_CFG_OSC:
+  case SYS_CFG_VOLT:
+  case SYS_CFG_AMP:
+  case SYS_CFG_TEMP:
+  case SYS_CFG_RESET:
+  case SYS_CFG_SCC:
+  case SYS_CFG_DVIMODE:
+  case SYS_CFG_POWER:
+    Site = ARM_VE_MOTHERBOARD_SITE;
+    break;
+
+  case SYS_CFG_SHUTDOWN:
+  case SYS_CFG_REBOOT:
+  case SYS_CFG_RTC:
+  default:
+    return RETURN_UNSUPPORTED;
+  }
+
+  return AccessSysCfgRegister (SYS_CFGCTRL_READ, Function, Site, Position, Device, Value);
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigGetValues (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINTN                 Size,
+  OUT UINT32*               Values
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigSet (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINT32                Value
+  )
+{
+  UINT32          Site;
+  UINT32          Position;
+  UINT32          Device;
+
+  Position = 0;
+  Device = 0;
+
+  // Intercept some functions
+  switch(Function) {
+
+  case SYS_CFG_OSC_SITE1:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_1_SITE;
+    break;
+
+  case SYS_CFG_OSC_SITE2:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_2_SITE;
+    break;
+
+  case SYS_CFG_MUXFPGA:
+    Site = Value;
+    break;
+
+  case SYS_CFG_RESET:
+  case SYS_CFG_SCC:
+  case SYS_CFG_SHUTDOWN:
+  case SYS_CFG_REBOOT:
+  case SYS_CFG_DVIMODE:
+  case SYS_CFG_POWER:
+    Site = ARM_VE_MOTHERBOARD_SITE;
+    break;
+
+  case SYS_CFG_OSC:
+  case SYS_CFG_VOLT:
+  case SYS_CFG_AMP:
+  case SYS_CFG_TEMP:
+  case SYS_CFG_RTC:
+  default:
+    return RETURN_UNSUPPORTED;
+  }
+
+  return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value);
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigSetDevice (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINT32                Device,
+  IN  UINT32                Value
+  )
+{
+  UINT32          Site;
+  UINT32          Position;
+
+  Position = 0;
+
+  // Intercept some functions
+  switch(Function) {
+  case SYS_CFG_SCC:
+#ifdef ARM_VE_SCC_BASE
+    MmioWrite32 ((ARM_VE_SCC_BASE + (Device * 4)),Value);
+    return RETURN_SUCCESS;
+#else
+    // There is no System Configuration Controller on the Model
+    return RETURN_UNSUPPORTED;
+#endif
+
+  case SYS_CFG_OSC_SITE1:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_1_SITE;
+    break;
+
+  case SYS_CFG_OSC_SITE2:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_2_SITE;
+    break;
+
+  case SYS_CFG_MUXFPGA:
+    Site = Value;
+    break;
+
+  case SYS_CFG_RTC:
+    return RETURN_UNSUPPORTED;
+    //break;
+
+  case SYS_CFG_OSC:
+  case SYS_CFG_VOLT:
+  case SYS_CFG_AMP:
+  case SYS_CFG_TEMP:
+  case SYS_CFG_RESET:
+  case SYS_CFG_SHUTDOWN:
+  case SYS_CFG_REBOOT:
+  case SYS_CFG_DVIMODE:
+  case SYS_CFG_POWER:
+    Site = ARM_VE_MOTHERBOARD_SITE;
+    break;
+  default:
+    return RETURN_UNSUPPORTED;
+  }
+
+  return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value);
+}
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
new file mode 100644
index 000000000000..c400ab831ab1
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
@@ -0,0 +1,35 @@
+#/** @file
+#
+#  Component description file for ArmVExpressSysConfigLib module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmVExpressSysConfigLib
+  FILE_GUID                      = a05b5cc0-82d2-11e0-82cb-0002a5d5c51b
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformSysConfigLib|SEC DXE_DRIVER
+
+[Sources.common]
+  ArmVExpressSysConfig.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  IoLib
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c
new file mode 100644
index 000000000000..1f915e3b0225
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.c
@@ -0,0 +1,283 @@
+/** @file  ArmVExpressSysConfig.c
+
+  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/ArmPlatformSysConfigLib.h>
+#include <ArmPlatform.h>
+
+#include <Uefi.h>
+#include <Library/UefiRuntimeLib.h>
+
+//
+// SYS_CFGCTRL Bits
+//
+#define SYS_CFGCTRL_START                 BIT31
+#define SYS_CFGCTRL_READ                  (0 << 30)
+#define SYS_CFGCTRL_WRITE                 (1 << 30)
+#define SYS_CFGCTRL_FUNCTION(fun)         (((fun ) &  0x3F) << 20)
+#define SYS_CFGCTRL_SITE(site)            (((site) &   0x3) << 16)
+#define SYS_CFGCTRL_POSITION(pos)         (((pos ) &   0xF) << 12)
+#define SYS_CFGCTRL_DEVICE(dev)            ((dev ) & 0xFFF)
+
+//
+// SYS_CFGSTAT Bits
+//
+#define SYS_CFGSTAT_ERROR                 BIT1
+#define SYS_CFGSTAT_COMPLETE              BIT0
+
+/****************************************************************************
+ *
+ *  This file makes it easier to access the System Configuration Registers
+ *  in the ARM Versatile Express motherboard.
+ *
+ ****************************************************************************/
+
+RETURN_STATUS
+ArmPlatformSysConfigInitialize (
+  VOID
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+/***************************************
+ * GENERAL FUNCTION: AccessSysCfgRegister
+ * Interacts with
+ *    SYS_CFGSTAT
+ *    SYS_CFGDATA
+ *    SYS_CFGCTRL
+ * for setting and for reading out values
+ ***************************************/
+
+RETURN_STATUS
+AccessSysCfgRegister (
+  IN     UINT32   ReadWrite,
+  IN     UINT32   Function,
+  IN     UINT32   Site,
+  IN     UINT32   Position,
+  IN     UINT32   Device,
+  IN OUT UINT32*  Data
+  )
+{
+  UINT32          SysCfgCtrl;
+
+  if (EfiAtRuntime ()) {
+    return RETURN_UNSUPPORTED;
+  }
+
+  // Clear the COMPLETE bit
+  MmioAnd32(ARM_VE_SYS_CFGSTAT_REG, ~SYS_CFGSTAT_COMPLETE);
+
+  // If writing, then set the data value
+  if(ReadWrite == SYS_CFGCTRL_WRITE) {
+    MmioWrite32(ARM_VE_SYS_CFGDATA_REG, *Data);
+  }
+
+  // Set the control value
+  SysCfgCtrl = SYS_CFGCTRL_START | ReadWrite | SYS_CFGCTRL_FUNCTION(Function) | SYS_CFGCTRL_SITE(Site) |
+      SYS_CFGCTRL_POSITION(Position) | SYS_CFGCTRL_DEVICE(Device);
+  MmioWrite32(ARM_VE_SYS_CFGCTRL_REG, SysCfgCtrl);
+
+  // Wait until the COMPLETE bit is set
+  while ((MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_COMPLETE) == 0);
+
+  // Check for errors
+  if(MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_ERROR) {
+    return RETURN_DEVICE_ERROR;
+  }
+
+  // If reading then get the data value
+  if(ReadWrite == SYS_CFGCTRL_READ) {
+    *Data = MmioRead32(ARM_VE_SYS_CFGDATA_REG);
+  }
+
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigGet (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  OUT UINT32*               Value
+  )
+{
+  UINT32          Site;
+  UINT32          Position;
+  UINT32          Device;
+
+  Position = 0;
+  Device = 0;
+
+  // Intercept some functions
+  switch(Function) {
+
+  case SYS_CFG_OSC_SITE1:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_1_SITE;
+    break;
+
+  case SYS_CFG_OSC_SITE2:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_2_SITE;
+    break;
+
+  case SYS_CFG_MUXFPGA:
+    Site = *Value;
+    break;
+
+  case SYS_CFG_OSC:
+  case SYS_CFG_VOLT:
+  case SYS_CFG_AMP:
+  case SYS_CFG_TEMP:
+  case SYS_CFG_RESET:
+  case SYS_CFG_SCC:
+  case SYS_CFG_DVIMODE:
+  case SYS_CFG_POWER:
+    Site = ARM_VE_MOTHERBOARD_SITE;
+    break;
+
+  case SYS_CFG_SHUTDOWN:
+  case SYS_CFG_REBOOT:
+  case SYS_CFG_RTC:
+  default:
+    return RETURN_UNSUPPORTED;
+  }
+
+  return AccessSysCfgRegister (SYS_CFGCTRL_READ, Function, Site, Position, Device, Value);
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigGetValues (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINTN                 Size,
+  OUT UINT32*               Values
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigSet (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINT32                Value
+  )
+{
+  UINT32          Site;
+  UINT32          Position;
+  UINT32          Device;
+
+  Position = 0;
+  Device = 0;
+
+  // Intercept some functions
+  switch(Function) {
+
+  case SYS_CFG_OSC_SITE1:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_1_SITE;
+    break;
+
+  case SYS_CFG_OSC_SITE2:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_2_SITE;
+    break;
+
+  case SYS_CFG_MUXFPGA:
+    Site = Value;
+    break;
+
+  case SYS_CFG_RESET:
+  case SYS_CFG_SCC:
+  case SYS_CFG_SHUTDOWN:
+  case SYS_CFG_REBOOT:
+  case SYS_CFG_DVIMODE:
+  case SYS_CFG_POWER:
+    Site = ARM_VE_MOTHERBOARD_SITE;
+    break;
+
+  case SYS_CFG_OSC:
+  case SYS_CFG_VOLT:
+  case SYS_CFG_AMP:
+  case SYS_CFG_TEMP:
+  case SYS_CFG_RTC:
+  default:
+    return RETURN_UNSUPPORTED;
+  }
+
+  return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value);
+}
+
+RETURN_STATUS
+ArmPlatformSysConfigSetDevice (
+  IN  SYS_CONFIG_FUNCTION   Function,
+  IN  UINT32                Device,
+  IN  UINT32                Value
+  )
+{
+  UINT32          Site;
+  UINT32          Position;
+
+  Position = 0;
+
+  // Intercept some functions
+  switch(Function) {
+  case SYS_CFG_SCC:
+#ifdef ARM_VE_SCC_BASE
+    if (EfiAtRuntime ()) {
+      return RETURN_UNSUPPORTED;
+    }
+    MmioWrite32 ((ARM_VE_SCC_BASE + (Device * 4)),Value);
+    return RETURN_SUCCESS;
+#else
+    // There is no System Configuration Controller on the Model
+    return RETURN_UNSUPPORTED;
+#endif
+
+  case SYS_CFG_OSC_SITE1:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_1_SITE;
+    break;
+
+  case SYS_CFG_OSC_SITE2:
+    Function = SYS_CFG_OSC;
+    Site = ARM_VE_DAUGHTERBOARD_2_SITE;
+    break;
+
+  case SYS_CFG_MUXFPGA:
+    Site = Value;
+    break;
+
+  case SYS_CFG_RTC:
+    return RETURN_UNSUPPORTED;
+    //break;
+
+  case SYS_CFG_OSC:
+  case SYS_CFG_VOLT:
+  case SYS_CFG_AMP:
+  case SYS_CFG_TEMP:
+  case SYS_CFG_RESET:
+  case SYS_CFG_SHUTDOWN:
+  case SYS_CFG_REBOOT:
+  case SYS_CFG_DVIMODE:
+  case SYS_CFG_POWER:
+    Site = ARM_VE_MOTHERBOARD_SITE;
+    break;
+  default:
+    return RETURN_UNSUPPORTED;
+  }
+
+  return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value);
+}
diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
new file mode 100644
index 000000000000..cce8b9096f6d
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressSysConfigRuntimeLib/ArmVExpressSysConfigRuntimeLib.inf
@@ -0,0 +1,37 @@
+#/** @file
+#
+#  Component description file for ArmVExpressSysConfigRuntimeLib module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmVExpressSysConfigRuntimeLib
+  FILE_GUID                      = 6275b819-615c-4a36-814a-c1f330b4e5d9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformSysConfigLib|DXE_RUNTIME_DRIVER
+
+[Sources.common]
+  ArmVExpressSysConfigRuntimeLib.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  UefiRuntimeLib
diff --git a/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c
new file mode 100644
index 000000000000..b1106ee19b98
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c
@@ -0,0 +1,285 @@
+/**
+
+  Copyright (c) 2012, ARM Ltd. All rights reserved.
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/ArmPlatformSysConfigLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/LcdPlatformLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EdidDiscovered.h>
+#include <Protocol/EdidActive.h>
+
+#include <ArmPlatform.h>
+
+typedef struct {
+  UINT32                     Mode;
+  UINT32                     HorizontalResolution;
+  UINT32                     VerticalResolution;
+  LCD_BPP                    Bpp;
+  UINT32                     OscFreq;
+
+  // These are used by HDLCD
+  UINT32                     HSync;
+  UINT32                     HBackPorch;
+  UINT32                     HFrontPorch;
+  UINT32                     VSync;
+  UINT32                     VBackPorch;
+  UINT32                     VFrontPorch;
+} LCD_RESOLUTION;
+
+
+LCD_RESOLUTION mResolutions[] = {
+  { // Mode 0 : VGA : 640 x 480 x 24 bpp
+    VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,
+    VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,
+    VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH
+  },
+  { // Mode 1 : SVGA : 800 x 600 x 24 bpp
+    SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,
+    SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,
+    SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH
+  },
+  { // Mode 2 : XGA : 1024 x 768 x 24 bpp
+    XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,
+    XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
+    XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
+  },
+  { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp
+    SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),
+    SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,
+    SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH
+  },
+  { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp
+    UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),
+    UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,
+    UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH
+  },
+  { // Mode 5 : HD : 1920 x 1080 x 24 bpp
+    HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),
+    HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,
+    HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH
+  }
+};
+
+EFI_EDID_DISCOVERED_PROTOCOL  mEdidDiscovered = {
+  0,
+  NULL
+};
+
+EFI_EDID_ACTIVE_PROTOCOL      mEdidActive = {
+  0,
+  NULL
+};
+
+EFI_STATUS
+LcdPlatformInitializeDisplay (
+  IN EFI_HANDLE   Handle
+  )
+{
+  EFI_STATUS  Status;
+
+  // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard
+  Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  // Install the EDID Protocols
+  Status = gBS->InstallMultipleProtocolInterfaces (
+    &Handle,
+    &gEfiEdidDiscoveredProtocolGuid,  &mEdidDiscovered,
+    &gEfiEdidActiveProtocolGuid,      &mEdidActive,
+    NULL
+  );
+
+  return Status;
+}
+
+EFI_STATUS
+LcdPlatformGetVram (
+  OUT EFI_PHYSICAL_ADDRESS*  VramBaseAddress,
+  OUT UINTN*                 VramSize
+  )
+{
+  EFI_STATUS              Status;
+  EFI_ALLOCATE_TYPE       AllocationType;
+
+  // Set the vram size
+  *VramSize = LCD_VRAM_SIZE;
+
+  *VramBaseAddress = (EFI_PHYSICAL_ADDRESS)LCD_VRAM_CORE_TILE_BASE;
+
+  // Allocate the VRAM from the DRAM so that nobody else uses it.
+  if (*VramBaseAddress == 0) {
+    AllocationType = AllocateAnyPages;
+  } else {
+    AllocationType = AllocateAddress;
+  }
+  Status = gBS->AllocatePages (AllocationType, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable.
+  Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize,
+                  EFI_MEMORY_WC);
+  ASSERT_EFI_ERROR(Status);
+  if (EFI_ERROR(Status)) {
+    gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES (*VramSize));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+UINT32
+LcdPlatformGetMaxMode (
+  VOID
+  )
+{
+  //
+  // The following line will report correctly the total number of graphics modes
+  // that could be supported by the graphics driver:
+  //
+  return (sizeof(mResolutions) / sizeof(LCD_RESOLUTION));
+}
+
+EFI_STATUS
+LcdPlatformSetMode (
+  IN UINT32                         ModeNumber
+  )
+{
+  EFI_STATUS            Status;
+
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Set the video mode oscillator
+  do {
+    Status = ArmPlatformSysConfigSetDevice (SYS_CFG_OSC_SITE1, PcdGet32(PcdHdLcdVideoModeOscId), mResolutions[ModeNumber].OscFreq);
+  } while (Status == EFI_TIMEOUT);
+  if (EFI_ERROR(Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  // Set the DVI into the new mode
+  do {
+    Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);
+  } while (Status == EFI_TIMEOUT);
+  if (EFI_ERROR(Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  // Set the multiplexer
+  Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE);
+  if (EFI_ERROR(Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+LcdPlatformQueryMode (
+  IN  UINT32                                ModeNumber,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
+  )
+{
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Info->Version = 0;
+  Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;
+  Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;
+  Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;
+
+  switch (mResolutions[ModeNumber].Bpp) {
+    case LCD_BITS_PER_PIXEL_24:
+      Info->PixelFormat                   = PixelRedGreenBlueReserved8BitPerColor;
+      Info->PixelInformation.RedMask      = LCD_24BPP_RED_MASK;
+      Info->PixelInformation.GreenMask    = LCD_24BPP_GREEN_MASK;
+      Info->PixelInformation.BlueMask     = LCD_24BPP_BLUE_MASK;
+      Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;
+      break;
+
+    case LCD_BITS_PER_PIXEL_16_555:
+    case LCD_BITS_PER_PIXEL_16_565:
+    case LCD_BITS_PER_PIXEL_12_444:
+    case LCD_BITS_PER_PIXEL_8:
+    case LCD_BITS_PER_PIXEL_4:
+    case LCD_BITS_PER_PIXEL_2:
+    case LCD_BITS_PER_PIXEL_1:
+    default:
+      // These are not supported
+      ASSERT(FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdPlatformGetTimings (
+  IN  UINT32                              ModeNumber,
+  OUT UINT32*                             HRes,
+  OUT UINT32*                             HSync,
+  OUT UINT32*                             HBackPorch,
+  OUT UINT32*                             HFrontPorch,
+  OUT UINT32*                             VRes,
+  OUT UINT32*                             VSync,
+  OUT UINT32*                             VBackPorch,
+  OUT UINT32*                             VFrontPorch
+  )
+{
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *HRes           = mResolutions[ModeNumber].HorizontalResolution;
+  *HSync          = mResolutions[ModeNumber].HSync;
+  *HBackPorch     = mResolutions[ModeNumber].HBackPorch;
+  *HFrontPorch    = mResolutions[ModeNumber].HFrontPorch;
+  *VRes           = mResolutions[ModeNumber].VerticalResolution;
+  *VSync          = mResolutions[ModeNumber].VSync;
+  *VBackPorch     = mResolutions[ModeNumber].VBackPorch;
+  *VFrontPorch    = mResolutions[ModeNumber].VFrontPorch;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdPlatformGetBpp (
+  IN  UINT32                              ModeNumber,
+  OUT LCD_BPP  *                          Bpp
+  )
+{
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Bpp = mResolutions[ModeNumber].Bpp;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
new file mode 100644
index 000000000000..fc51c781b451
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
@@ -0,0 +1,45 @@
+#/** @file
+#
+#  Component description file for HdLcdArmLib module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = HdLcdArmVExpress
+  FILE_GUID                      = 535a720e-06c0-4bb9-b563-452216abbed4
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = LcdPlatformLib
+
+[Sources.common]
+
+HdLcdArmVExpress.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  ArmPlatformSysConfigLib
+  BaseLib
+  DxeServicesTableLib
+
+[Protocols]
+  gEfiEdidDiscoveredProtocolGuid                # Produced
+  gEfiEdidActiveProtocolGuid                    # Produced
+
+[Pcd]
+  gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode
+  gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId
diff --git a/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c
new file mode 100644
index 000000000000..a136bff4a1d6
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c
@@ -0,0 +1,84 @@
+/** @file
+
+ Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NorFlashPlatformLib.h>
+#include <ArmPlatform.h>
+
+#define NOR_FLASH_DEVICE_COUNT                     4
+
+NOR_FLASH_DESCRIPTION mNorFlashDevices[NOR_FLASH_DEVICE_COUNT] = {
+  { // BootMon
+    ARM_VE_SMB_NOR0_BASE,
+    ARM_VE_SMB_NOR0_BASE,
+    SIZE_256KB * 255,
+    SIZE_256KB,
+    { 0xE7223039, 0x5836, 0x41E1, { 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59 } }
+  },
+  { // BootMon non-volatile storage
+    ARM_VE_SMB_NOR0_BASE,
+    ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255,
+    SIZE_64KB * 4,
+    SIZE_64KB,
+    { 0x02118005, 0x9DA7, 0x443A, { 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB } }
+  },
+  { // UEFI
+    ARM_VE_SMB_NOR1_BASE,
+    ARM_VE_SMB_NOR1_BASE,
+    SIZE_256KB * 255,
+    SIZE_256KB,
+    { 0x1F15DA3C, 0x37FF, 0x4070, { 0xB4, 0x71, 0xBB, 0x4A, 0xF1, 0x2A, 0x72, 0x4A } }
+  },
+  { // UEFI Variable Services non-volatile storage
+    ARM_VE_SMB_NOR1_BASE,
+    ARM_VE_SMB_NOR1_BASE + SIZE_256KB * 255,
+    SIZE_64KB * 3, //FIXME: Set 3 blocks because I did not succeed to copy 4 blocks into the ARM Versatile Express NOR Flash in the last NOR Flash. It should be 4 blocks
+    SIZE_64KB,
+    { 0xCC2CBF29, 0x1498, 0x4CDD, { 0x81, 0x71, 0xF8, 0xB6, 0xB4, 0x1D, 0x09, 0x09 } }
+  }
+};
+
+EFI_STATUS
+NorFlashPlatformInitialization (
+  VOID
+  )
+{
+  // Everything seems ok so far, so now we need to disable the platform-specific
+  // flash write protection for Versatile Express
+  if ((MmioRead32 (ARM_VE_SYS_FLASH) & 0x1) == 0) {
+    // Writing to NOR FLASH is disabled, so enable it
+    MmioWrite32 (ARM_VE_SYS_FLASH,1);
+    DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: informational - Had to enable HSYS_FLASH flag.\n" ));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashPlatformGetDevices (
+  OUT NOR_FLASH_DESCRIPTION   **NorFlashDevices,
+  OUT UINT32                  *Count
+  )
+{
+  if ((NorFlashDevices == NULL) || (Count == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *NorFlashDevices = mNorFlashDevices;
+  *Count = NOR_FLASH_DEVICE_COUNT;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
new file mode 100644
index 000000000000..6c0ca97c9900
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
@@ -0,0 +1,33 @@
+#/** @file
+#
+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = NorFlashArmVExpressLib
+  FILE_GUID                      = c0f5dfa0-7599-11e0-9665-0002a5d5c51b
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NorFlashPlatformLib
+
+[Sources.common]
+  NorFlashArmVExpress.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
diff --git a/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
new file mode 100644
index 000000000000..3f3ceb3d2fa8
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
@@ -0,0 +1,370 @@
+/** @file
+
+  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/ArmPlatformSysConfigLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/LcdPlatformLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EdidDiscovered.h>
+#include <Protocol/EdidActive.h>
+
+#include <ArmPlatform.h>
+
+typedef struct {
+  UINT32                     Mode;
+  UINT32                     HorizontalResolution;
+  UINT32                     VerticalResolution;
+  LCD_BPP                    Bpp;
+  UINT32                     OscFreq;
+
+  UINT32                     HSync;
+  UINT32                     HBackPorch;
+  UINT32                     HFrontPorch;
+  UINT32                     VSync;
+  UINT32                     VBackPorch;
+  UINT32                     VFrontPorch;
+} LCD_RESOLUTION;
+
+
+LCD_RESOLUTION mResolutions[] = {
+  { // Mode 0 : VGA : 640 x 480 x 24 bpp
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH
+  },
+  { // Mode 1 : SVGA : 800 x 600 x 24 bpp
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH
+  },
+  { // Mode 2 : XGA : 1024 x 768 x 24 bpp
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
+  },
+  { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp
+      SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),
+      SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,
+      SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH
+  },
+  { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp
+      UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),
+      UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,
+      UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH
+  },
+  { // Mode 5 : HD : 1920 x 1080 x 24 bpp
+      HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),
+      HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,
+      HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH
+  },
+  { // Mode 6 : VGA : 640 x 480 x 16 bpp (565 Mode)
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, VGA_OSC_FREQUENCY,
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH
+  },
+  { // Mode 7 : SVGA : 800 x 600 x 16 bpp (565 Mode)
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, SVGA_OSC_FREQUENCY,
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH
+  },
+  { // Mode 8 : XGA : 1024 x 768 x 16 bpp (565 Mode)
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, XGA_OSC_FREQUENCY,
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
+  },
+  { // Mode 9 : VGA : 640 x 480 x 15 bpp
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, VGA_OSC_FREQUENCY,
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH
+  },
+  { // Mode 10 : SVGA : 800 x 600 x 15 bpp
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, SVGA_OSC_FREQUENCY,
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH
+  },
+  { // Mode 11 : XGA : 1024 x 768 x 15 bpp
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, XGA_OSC_FREQUENCY,
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
+  },
+  { // Mode 12 : XGA : 1024 x 768 x 15 bpp - All the timing info is derived from Linux Kernel Driver Settings
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, 63500000,
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
+  },
+  { // Mode 13 : VGA : 640 x 480 x 12 bpp (444 Mode)
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, VGA_OSC_FREQUENCY,
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH
+  },
+  { // Mode 14 : SVGA : 800 x 600 x 12 bpp (444 Mode)
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, SVGA_OSC_FREQUENCY,
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH
+  },
+  { // Mode 15 : XGA : 1024 x 768 x 12 bpp (444 Mode)
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, XGA_OSC_FREQUENCY,
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
+  }
+};
+
+EFI_EDID_DISCOVERED_PROTOCOL  mEdidDiscovered = {
+  0,
+  NULL
+};
+
+EFI_EDID_ACTIVE_PROTOCOL      mEdidActive = {
+  0,
+  NULL
+};
+
+
+EFI_STATUS
+LcdPlatformInitializeDisplay (
+  IN EFI_HANDLE   Handle
+  )
+{
+  EFI_STATUS  Status;
+
+  // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard
+  Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE);
+  if (!EFI_ERROR(Status)) {
+    // Install the EDID Protocols
+    Status = gBS->InstallMultipleProtocolInterfaces(
+      &Handle,
+      &gEfiEdidDiscoveredProtocolGuid,  &mEdidDiscovered,
+      &gEfiEdidActiveProtocolGuid,      &mEdidActive,
+      NULL
+    );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+LcdPlatformGetVram (
+  OUT EFI_PHYSICAL_ADDRESS*  VramBaseAddress,
+  OUT UINTN*                 VramSize
+  )
+{
+  EFI_STATUS              Status;
+
+  Status = EFI_SUCCESS;
+
+  // Is it on the motherboard or on the daughterboard?
+  switch(PL111_CLCD_SITE) {
+
+  case ARM_VE_MOTHERBOARD_SITE:
+    *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) PL111_CLCD_VRAM_MOTHERBOARD_BASE;
+    *VramSize = LCD_VRAM_SIZE;
+    break;
+
+  case ARM_VE_DAUGHTERBOARD_1_SITE:
+    *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) LCD_VRAM_CORE_TILE_BASE;
+    *VramSize = LCD_VRAM_SIZE;
+
+    // Allocate the VRAM from the DRAM so that nobody else uses it.
+    Status = gBS->AllocatePages( AllocateAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+
+    // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable.
+    Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize,
+                    EFI_MEMORY_WC);
+    ASSERT_EFI_ERROR(Status);
+    if (EFI_ERROR(Status)) {
+      gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES(*VramSize));
+      return Status;
+    }
+    break;
+
+  default:
+    // Unsupported site
+    Status = EFI_UNSUPPORTED;
+    break;
+  }
+
+  return Status;
+}
+
+UINT32
+LcdPlatformGetMaxMode (
+  VOID
+  )
+{
+  // The following line will report correctly the total number of graphics modes
+  // supported by the PL111CLCD.
+  //return (sizeof(mResolutions) / sizeof(CLCD_RESOLUTION)) - 1;
+
+  // However, on some platforms it is desirable to ignore some graphics modes.
+  // This could be because the specific implementation of PL111 has certain limitations.
+
+  // Set the maximum mode allowed
+  return (PcdGet32(PcdPL111LcdMaxMode));
+}
+
+EFI_STATUS
+LcdPlatformSetMode (
+  IN UINT32                         ModeNumber
+  )
+{
+  EFI_STATUS            Status;
+  UINT32                LcdSite;
+  UINT32                OscillatorId;
+  SYS_CONFIG_FUNCTION   Function;
+  UINT32                SysId;
+
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  LcdSite = PL111_CLCD_SITE;
+
+  switch(LcdSite) {
+  case ARM_VE_MOTHERBOARD_SITE:
+    Function = SYS_CFG_OSC;
+    OscillatorId = PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID;
+    break;
+  case ARM_VE_DAUGHTERBOARD_1_SITE:
+    Function = SYS_CFG_OSC_SITE1;
+    OscillatorId = (UINT32)PcdGet32(PcdPL111LcdVideoModeOscId);
+    break;
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  // Set the video mode oscillator
+  Status = ArmPlatformSysConfigSetDevice (Function, OscillatorId, mResolutions[ModeNumber].OscFreq);
+  if (EFI_ERROR(Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  // The FVP foundation model does not have an LCD.
+  // On the FVP models the GIC variant in encoded in bits [15:12].
+  // Note: The DVI Mode is not modelled by RTSM or FVP models.
+  SysId = MmioRead32 (ARM_VE_SYS_ID_REG);
+  if (SysId != ARM_RTSM_SYS_ID) {
+    // Take out the FVP GIC variant to reduce the permutations.
+    SysId &= ~ARM_FVP_SYS_ID_VARIANT_MASK;
+    if (SysId != ARM_FVP_BASE_BOARD_SYS_ID) {
+      // Set the DVI into the new mode
+      Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);
+      if (EFI_ERROR(Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return Status;
+      }
+    }
+  }
+
+  // Set the multiplexer
+  Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, LcdSite);
+  if (EFI_ERROR(Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+LcdPlatformQueryMode (
+  IN  UINT32                                ModeNumber,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
+  )
+{
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Info->Version = 0;
+  Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;
+  Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;
+  Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;
+
+  switch (mResolutions[ModeNumber].Bpp) {
+    case LCD_BITS_PER_PIXEL_24:
+      Info->PixelFormat                   = PixelRedGreenBlueReserved8BitPerColor;
+      Info->PixelInformation.RedMask      = LCD_24BPP_RED_MASK;
+      Info->PixelInformation.GreenMask    = LCD_24BPP_GREEN_MASK;
+      Info->PixelInformation.BlueMask     = LCD_24BPP_BLUE_MASK;
+      Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;
+      break;
+
+    case LCD_BITS_PER_PIXEL_16_555:
+    case LCD_BITS_PER_PIXEL_16_565:
+    case LCD_BITS_PER_PIXEL_12_444:
+    case LCD_BITS_PER_PIXEL_8:
+    case LCD_BITS_PER_PIXEL_4:
+    case LCD_BITS_PER_PIXEL_2:
+    case LCD_BITS_PER_PIXEL_1:
+    default:
+      // These are not supported
+      ASSERT(FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdPlatformGetTimings (
+  IN  UINT32                              ModeNumber,
+  OUT UINT32*                             HRes,
+  OUT UINT32*                             HSync,
+  OUT UINT32*                             HBackPorch,
+  OUT UINT32*                             HFrontPorch,
+  OUT UINT32*                             VRes,
+  OUT UINT32*                             VSync,
+  OUT UINT32*                             VBackPorch,
+  OUT UINT32*                             VFrontPorch
+  )
+{
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *HRes           = mResolutions[ModeNumber].HorizontalResolution;
+  *HSync          = mResolutions[ModeNumber].HSync;
+  *HBackPorch     = mResolutions[ModeNumber].HBackPorch;
+  *HFrontPorch    = mResolutions[ModeNumber].HFrontPorch;
+  *VRes           = mResolutions[ModeNumber].VerticalResolution;
+  *VSync          = mResolutions[ModeNumber].VSync;
+  *VBackPorch     = mResolutions[ModeNumber].VBackPorch;
+  *VFrontPorch    = mResolutions[ModeNumber].VFrontPorch;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdPlatformGetBpp (
+  IN  UINT32                              ModeNumber,
+  OUT LCD_BPP  *                          Bpp
+  )
+{
+  if (ModeNumber >= LcdPlatformGetMaxMode ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Bpp = mResolutions[ModeNumber].Bpp;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
new file mode 100644
index 000000000000..658558ab1523
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
@@ -0,0 +1,44 @@
+#/** @file
+#
+#  Component description file for ArmVeGraphicsDxe module
+#
+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PL111LcdArmVExpressLib
+  FILE_GUID                      = b7f06f20-496f-11e0-a8e8-0002a5d5c51b
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = LcdPlatformLib
+
+[Sources.common]
+  PL111LcdArmVExpress.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+  ArmPlatformSysConfigLib
+  BaseLib
+  DxeServicesTableLib
+
+[Protocols]
+  gEfiEdidDiscoveredProtocolGuid                # Produced
+  gEfiEdidActiveProtocolGuid                    # Produced
+
+[Pcd]
+  gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode
+  gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId
diff --git a/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 000000000000..d2bc4a88fa5a
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,111 @@
+/** @file
+  Template library implementation to support ResetSystem Runtime call.
+
+  Fill in the templates with what ever makes you system reset.
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+#include <Library/ArmPlatformSysConfigLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ResetSystemLib.h>
+
+#include <ArmPlatform.h>
+
+/**
+  This function causes a system-wide reset (cold reset), in which
+  all circuitry within the system returns to its initial state. This type of
+  reset is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  If this function returns, it means that the system does not support cold
+  reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  )
+{
+  ArmPlatformSysConfigSet (SYS_CFG_REBOOT, 0);
+}
+
+/**
+  This function causes a system-wide initialization (warm reset), in which all
+  processors are set to their initial state. Pending cycles are not corrupted.
+
+  If this function returns, it means that the system does not support warm
+  reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  )
+{
+  ResetCold ();
+}
+
+/**
+  This function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  If this function returns, it means that the system does not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  )
+{
+  ArmPlatformSysConfigSet (SYS_CFG_SHUTDOWN, 0);
+}
+
+/**
+  This function causes the system to enter S3 and then wake up immediately.
+
+  If this function returns, it means that the system does not support S3
+  feature.
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+  VOID
+  )
+{
+  // not implemented
+}
+
+/**
+  This function causes a systemwide reset. The exact type of the reset is
+  defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+  the platform must pick a supported reset type to perform.The platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN   DataSize,
+  IN VOID    *ResetData
+  )
+{
+  ResetCold ();
+}
diff --git a/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 000000000000..e7caf04f7f74
--- /dev/null
+++ b/Platform/ARM/VExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,36 @@
+#/** @file
+# Reset System lib to make it easy to port new platforms
+#
+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmVeResetSystemLib
+  FILE_GUID                      = 36885202-0854-4373-bfd2-95d229b44d44
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ResetSystemLib
+
+[Sources.common]
+  ResetSystemLib.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/VExpressPkg/ArmVExpressPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  ArmPlatformSysConfigLib
-- 
2.11.0



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

* [PATCH edk2-platforms v2 07/13] Platform/ARM: remove outdated SP804 TimerLib reference
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (5 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 06/13] Platform/ARM/VExpress: import VExpressPkg " Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 08/13] Platform/Hisilicon: remove SP804 PCD definitions Ard Biesheuvel
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

ArmVExpress.dsc.inc declares a TimerLib dependency and resolves it
using ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf, but
all users of the include file supersede it with ArmArchTimerLib.inf
so let's just use that instead.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/JunoPkg/ArmJuno.dsc                     | 1 -
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc    | 1 -
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc | 2 --
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc         | 3 +--
 4 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/Platform/ARM/JunoPkg/ArmJuno.dsc b/Platform/ARM/JunoPkg/ArmJuno.dsc
index 187c9f5602e5..80a5ef631ce9 100644
--- a/Platform/ARM/JunoPkg/ArmJuno.dsc
+++ b/Platform/ARM/JunoPkg/ArmJuno.dsc
@@ -41,7 +41,6 @@ [LibraryClasses.common]
 
   NorFlashPlatformLib|Platform/ARM/JunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
 
-  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
 
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
index 51da85fe8bc0..4a55dac7a4a4 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -51,7 +51,6 @@ [LibraryClasses.common]
 
   LcdPlatformLib|Platform/ARM/VExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
 
-  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
   ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
 
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
index df6951900ed8..829854963b30 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
@@ -49,8 +49,6 @@ [LibraryClasses.common]
   LcdPlatformLib|Platform/ARM/VExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
 !endif
 
-  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
-
   # Virtio Support
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 40e1c868fcb2..269636878977 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -93,8 +93,7 @@ [LibraryClasses.common]
   # ARM PL011 UART Driver
   PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
-  # ARM SP804 Dual Timer Driver
-  TimerLib|ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
 
   # EBL Related Libraries
   EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
-- 
2.11.0



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

* [PATCH edk2-platforms v2 08/13] Platform/Hisilicon: remove SP804 PCD definitions
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (6 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 07/13] Platform/ARM: remove outdated SP804 TimerLib reference Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 09/13] Platform: remove references to EBL libraries Ard Biesheuvel
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

These platforms don't actually include the SP804 driver so no need
to set the PCDs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/Hisilicon/D02/Pv660D02.dsc | 8 --------
 Platform/Hisilicon/D03/D03.dsc      | 8 --------
 2 files changed, 16 deletions(-)

diff --git a/Platform/Hisilicon/D02/Pv660D02.dsc b/Platform/Hisilicon/D02/Pv660D02.dsc
index ba3047882611..cd0fbdb56fdf 100644
--- a/Platform/Hisilicon/D02/Pv660D02.dsc
+++ b/Platform/Hisilicon/D02/Pv660D02.dsc
@@ -201,14 +201,6 @@ [PcdsFixedAtBuild.common]
   gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
 
-  ## SP804 DualTimer
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz|200
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum|304
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase|0x80060000
-  ## TODO: need to confirm the base for Performance and Metronome base for PV660
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase|0x80060000
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase|0x80060000
-
   gHisiTokenSpaceGuid.PcdPcieRootBridgeMask|0x6 # bit0:HB0RB0,bit1:HB0RB1,bit2:HB0RB2,bit3:HB0RB3,bit4:HB1RB0,bit5:HB1RB1,bit6:HB1RB2,bit7:HB1RB3
   gHisiTokenSpaceGuid.PcdHb1BaseAddress|0x400000000000 # 4T
 
diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc
index 491862a3b27e..a5aa5f7fcd0a 100644
--- a/Platform/Hisilicon/D03/D03.dsc
+++ b/Platform/Hisilicon/D03/D03.dsc
@@ -286,14 +286,6 @@ [PcdsFixedAtBuild.common]
   gHisiTokenSpaceGuid.PcdHb0Rb2IoSize|0xffff #64K
 
   gHisiTokenSpaceGuid.Pcdsoctype|0x1610
-  ## SP804 DualTimer
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz|200
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum|0xb0
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase|0x40060000
-  ## TODO: need to confirm the base for Performance and Metronome base for PV660
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase|0x40060000
-  gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase|0x40060000
-
 
 ################################################################################
 #
-- 
2.11.0



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

* [PATCH edk2-platforms v2 09/13] Platform: remove references to EBL libraries
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (7 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 08/13] Platform/Hisilicon: remove SP804 PCD definitions Ard Biesheuvel
@ 2017-11-16 17:58 ` Ard Biesheuvel
  2017-11-16 18:00 ` [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references Ard Biesheuvel
  2017-11-25 12:12 ` [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Leif Lindholm
  10 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 17:58 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

None of these platforms still include EBL, but some references
remained to its support libraries. Get rid of that.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc | 6 ------
 Platform/Marvell/Armada/Armada.dsc.inc       | 6 ------
 Silicon/Hisilicon/Hisilicon.dsc.inc          | 6 ------
 3 files changed, 18 deletions(-)

diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 269636878977..079c743dd2e9 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -95,12 +95,6 @@ [LibraryClasses.common]
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
 
-  # EBL Related Libraries
-  EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
-  EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
-  EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
-  EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.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
diff --git a/Platform/Marvell/Armada/Armada.dsc.inc b/Platform/Marvell/Armada/Armada.dsc.inc
index 2cd96e60a82c..77f08c419417 100644
--- a/Platform/Marvell/Armada/Armada.dsc.inc
+++ b/Platform/Marvell/Armada/Armada.dsc.inc
@@ -105,12 +105,6 @@ [LibraryClasses.common]
   FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
   SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
 
-  # EBL Related Libraries
-  EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
-  EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
-  EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
-  EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.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
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index f24f6dabd12c..84e5a38475be 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -72,12 +72,6 @@ [LibraryClasses.common]
   SerialPortLib|Silicon/Hisilicon/Library/Dw8250SerialPortLib/Dw8250SerialPortLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
 
-  # EBL Related Libraries
-  EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
-  EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
-  EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
-  EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
-
   UefiDevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
   #
   # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
-- 
2.11.0



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

* [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (8 preceding siblings ...)
  2017-11-16 17:58 ` [PATCH edk2-platforms v2 09/13] Platform: remove references to EBL libraries Ard Biesheuvel
@ 2017-11-16 18:00 ` Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 11/13] Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2 Ard Biesheuvel
                     ` (2 more replies)
  2017-11-25 12:12 ` [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Leif Lindholm
  10 siblings, 3 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 18:00 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

No drivers actually use PL35xSmcLib so remove any resolutions for it.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc | 2 --
 Silicon/Hisilicon/Hisilicon.dsc.inc          | 2 --
 2 files changed, 4 deletions(-)

diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 079c743dd2e9..0fbef7e378cd 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -88,8 +88,6 @@ [LibraryClasses.common]
   # ARM PL031 RTC Driver
   RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
   TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
-  # ARM PL354 SMC Driver
-  PL35xSmcLib|ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf
   # ARM PL011 UART Driver
   PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index 84e5a38475be..318c4ffeb250 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -64,8 +64,6 @@ [LibraryClasses.common]
 
   ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
 
-  # ARM PL354 SMC Driver
-  PL35xSmcLib|ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf
   # ARM PL011 UART Driver
   PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
 
-- 
2.11.0



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

* [PATCH edk2-platforms v2 11/13] Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2
  2017-11-16 18:00 ` [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references Ard Biesheuvel
@ 2017-11-16 18:00   ` Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 12/13] Platform: remove stale EBL related PCD setting Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 13/13] Platform: switch to new PL011UartLib Ard Biesheuvel
  2 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 18:00 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

BootMonFs and ArmShellCmdRunAxf are only used on development boards
manufactured by ARM itself, so let's keep it under Platform/ARM where
it belongs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/ARM.dec                                         |   25 +
 Platform/ARM/Drivers/BootMonFs/BootMonFs.dec                 |   26 +
 Platform/ARM/Drivers/BootMonFs/BootMonFs.inf                 |   63 ++
 Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h                |  388 +++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c                |  766 ++++++++++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c         |  529 ++++++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h                 |   57 ++
 Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c             |  222 ++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h           |  101 ++
 Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c          |  795 +++++++++++++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c          |  259 +++++
 Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c        |   37 +
 Platform/ARM/Include/Guid/BootMonFsFileInfo.h                |   47 +
 Platform/ARM/Include/Library/ArmShellCmdLib.h                |   57 ++
 Platform/ARM/JunoPkg/ArmJuno.dsc                             |    2 +-
 Platform/ARM/JunoPkg/ArmJuno.fdf                             |    2 +-
 Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf       |    1 +
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c   |   95 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h   |   83 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf |   54 +
 Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni |   68 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c     |  154 +++
 Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h     |   66 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c           |  340 +++++++
 Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h           |   64 ++
 Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c              |  395 ++++++++
 Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h               |  258 +++++
 Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h               |  260 +++++
 Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h          | 1059 ++++++++++++++++++++
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf            |    2 +-
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc                 |    6 +-
 Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf |    1 +
 32 files changed, 6276 insertions(+), 6 deletions(-)

diff --git a/Platform/ARM/ARM.dec b/Platform/ARM/ARM.dec
new file mode 100644
index 000000000000..f9bf3294a0ca
--- /dev/null
+++ b/Platform/ARM/ARM.dec
@@ -0,0 +1,25 @@
+#/** @file
+#
+#  Copyright (c) 2011-2017, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001A
+  PACKAGE_NAME                   = ARM
+  PACKAGE_GUID                   = 2a905d2b-30c9-4408-86a2-c0b328876aee
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  Include                        # Root include for the package
+
+[Guids]
+  gArmBootMonFsFileInfoGuid   = { 0x41e26b9c, 0xada6, 0x45b3, { 0x80, 0x8e, 0x23, 0x57, 0xa3, 0x5b, 0x60, 0xd6 } }
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFs.dec b/Platform/ARM/Drivers/BootMonFs/BootMonFs.dec
new file mode 100644
index 000000000000..533dee3b616c
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFs.dec
@@ -0,0 +1,26 @@
+#/** @file
+#
+#  Copyright (c) 2011-2017, ARM Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001A
+  PACKAGE_NAME                   = BootMonFs
+  PACKAGE_GUID                   = 41f14aba-452f-4204-a435-25242973c5b1
+  PACKAGE_VERSION                = 0.1
+
+[Guids.common]
+  gArmBootMonFsTokenSpaceGuid = { 0xeb76a201, 0x69b4, 0x491f, { 0x9b, 0xde, 0xbf, 0x30, 0xbd, 0x03, 0x82, 0xb4 } }
+
+[PcdsFixedAtBuild.common]
+  # Boot Monitor FileSystem
+  gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L""|VOID*|0x0000003A
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFs.inf b/Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
new file mode 100644
index 000000000000..5b9353f0ee21
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
@@ -0,0 +1,63 @@
+#/** @file
+#  Support for ARM Boot Monitor File System
+#
+#  Copyright (c) 2012-2015, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BootMonFs
+  FILE_GUID                      = 7abbc454-f737-4322-931c-b1bb62a01d6f
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = BootMonFsEntryPoint
+
+[Sources]
+  BootMonFsEntryPoint.c
+  BootMonFsOpenClose.c
+  BootMonFsDir.c
+  BootMonFsImages.c
+  BootMonFsReadWrite.c
+  BootMonFsUnsupported.c
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/ARM/ARM.dec
+  Platform/ARM/Drivers/BootMonFs/BootMonFs.dec
+
+[LibraryClasses]
+  BaseLib
+  DevicePathLib
+  MemoryAllocationLib
+  PrintLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gArmBootMonFsFileInfoGuid
+  gEfiFileSystemInfoGuid
+  gEfiFileInfoGuid
+  gEfiFileSystemVolumeLabelInfoIdGuid
+
+[Pcd]
+  gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths
+
+[Protocols]
+  gEfiDiskIoProtocolGuid
+  gEfiBlockIoProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiDevicePathFromTextProtocolGuid
+
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h b/Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h
new file mode 100644
index 000000000000..d690520a0f67
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsApi.h
@@ -0,0 +1,388 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __BOOTMON_FS_API_H
+#define __BOOTMON_FS_API_H
+
+#include <Protocol/SimpleFileSystem.h>
+
+EFI_STATUS
+BootMonFsInitialize (
+  IN BOOTMON_FS_INSTANCE *Instance
+  );
+
+UINT32
+BootMonFsChecksum (
+  IN VOID   *Data,
+  IN UINT32 Size
+  );
+
+EFI_STATUS
+BootMonFsComputeFooterChecksum (
+  IN OUT HW_IMAGE_DESCRIPTION *Footer
+  );
+
+EFIAPI
+EFI_STATUS
+OpenBootMonFsOpenVolume (
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+  OUT EFI_FILE_PROTOCOL              **Root
+  );
+
+UINT32
+BootMonFsGetImageLength (
+  IN BOOTMON_FS_FILE      *File
+  );
+
+UINTN
+BootMonFsGetPhysicalSize (
+  IN BOOTMON_FS_FILE* File
+  );
+
+EFI_STATUS
+BootMonFsCreateFile (
+  IN  BOOTMON_FS_INSTANCE *Instance,
+  OUT BOOTMON_FS_FILE     **File
+  );
+
+EFIAPI
+EFI_STATUS
+BootMonFsGetInfo (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN EFI_GUID           *InformationType,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  );
+
+EFIAPI
+EFI_STATUS
+BootMonFsReadDirectory (
+  IN EFI_FILE_PROTOCOL    *This,
+  IN OUT UINTN            *BufferSize,
+  OUT VOID                *Buffer
+  );
+
+EFIAPI
+EFI_STATUS
+BootMonFsFlushDirectory (
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+/**
+  Flush all modified data associated with a file to a device.
+
+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the
+                    file handle to flush.
+
+  @retval  EFI_SUCCESS            The data was flushed.
+  @retval  EFI_ACCESS_DENIED      The file was opened read-only.
+  @retval  EFI_DEVICE_ERROR       The device reported an error.
+  @retval  EFI_VOLUME_FULL        The volume is full.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to flush the data.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsFlushFile (
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+/**
+  Close a specified file handle.
+
+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                    handle to close.
+
+  @retval  EFI_SUCCESS            The file was closed.
+  @retval  EFI_INVALID_PARAMETER  The parameter "This" is NULL or is not an open
+                                  file handle.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsCloseFile (
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+/**
+  Open a file on the boot monitor file system.
+
+  The boot monitor file system does not allow for sub-directories. There is only
+  one directory, the root one. On any attempt to create a directory, the function
+  returns in error with the EFI_WRITE_PROTECTED error code.
+
+  @param[in]   This        A pointer to the EFI_FILE_PROTOCOL instance that is
+                           the file handle to source location.
+  @param[out]  NewHandle   A pointer to the location to return the opened
+                           handle for the new file.
+  @param[in]   FileName    The Null-terminated string of the name of the file
+                           to be opened.
+  @param[in]   OpenMode    The mode to open the file : Read or Read/Write or
+                           Read/Write/Create
+  @param[in]   Attributes  Attributes of the file in case of a file creation
+
+  @retval  EFI_SUCCESS            The file was open.
+  @retval  EFI_NOT_FOUND          The specified file could not be found or the specified
+                                  directory in which to create a file could not be found.
+  @retval  EFI_DEVICE_ERROR       The device reported an error.
+  @retval  EFI_WRITE_PROTECTED    Attempt to create a directory. This is not possible
+                                  with the Boot Monitor file system.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to open the file.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsOpenFile (
+  IN EFI_FILE_PROTOCOL  *This,
+  OUT EFI_FILE_PROTOCOL **NewHandle,
+  IN CHAR16             *FileName,
+  IN UINT64             OpenMode,
+  IN UINT64             Attributes
+  );
+
+/**
+  Read data from an open file.
+
+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that
+                              is the file handle to read data from.
+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the
+                              amount of data returned in Buffer. In both cases,
+                              the size is measured in bytes.
+  @param[out]     Buffer      The buffer into which the data is read.
+
+  @retval  EFI_SUCCESS            The data was read.
+  @retval  EFI_DEVICE_ERROR       On entry, the current file position is
+                                  beyond the end of the file, or the device
+                                  reported an error while performing the read
+                                  operation.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsReadFile (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  );
+
+EFIAPI
+EFI_STATUS
+BootMonFsSetDirPosition (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN UINT64             Position
+  );
+
+EFIAPI
+EFI_STATUS
+BootMonFsGetPosition (
+  IN EFI_FILE_PROTOCOL  *This,
+  OUT UINT64            *Position
+  );
+
+/**
+  Write data to an open file.
+
+  The data is not written to the flash yet. It will be written when the file
+  will be either read, closed or flushed.
+
+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that
+                              is the file handle to write data to.
+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the
+                              size of the data actually written. In both cases,
+                              the size is measured in bytes.
+  @param[in]      Buffer      The buffer of data to write.
+
+  @retval  EFI_SUCCESS            The data was written.
+  @retval  EFI_ACCESS_DENIED      The file was opened read only.
+  @retval  EFI_OUT_OF_RESOURCES   Unable to allocate the buffer to store the
+                                  data to write.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsWriteFile (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN          *BufferSize,
+  IN VOID               *Buffer
+  );
+
+EFIAPI
+EFI_STATUS
+BootMonFsDeleteFail (
+  IN EFI_FILE_PROTOCOL *This
+  );
+
+/**
+  Close and delete a file from the boot monitor file system.
+
+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                    handle to delete.
+
+  @retval  EFI_SUCCESS              The file was closed and deleted.
+  @retval  EFI_INVALID_PARAMETER    The parameter "This" is NULL or is not an open
+                                    file handle.
+  @retval  EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsDelete (
+  IN EFI_FILE_PROTOCOL *This
+  );
+
+/**
+  Set a file's current position.
+
+  @param[in]  This      A pointer to the EFI_FILE_PROTOCOL instance that is
+                        the file handle to set the requested position on.
+  @param[in]  Position  The byte position from the start of the file to set.
+
+  @retval  EFI_SUCCESS            The position was set.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsSetPosition (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN UINT64             Position
+  );
+
+/**
+  Return a file's current position.
+
+  @param[in]   This      A pointer to the EFI_FILE_PROTOCOL instance that is
+                         the file handle to get the current position on.
+  @param[out]  Position  The address to return the file's current position value.
+
+  @retval  EFI_SUCCESS            The position was returned.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsGetPosition(
+  IN EFI_FILE_PROTOCOL  *This,
+  OUT UINT64            *Position
+  );
+
+//
+// UNSUPPORTED OPERATIONS
+//
+
+EFIAPI
+EFI_STATUS
+BootMonFsGetPositionUnsupported (
+  IN EFI_FILE_PROTOCOL  *This,
+  OUT UINT64            *Position
+  );
+
+/**
+  Set information about a file or a volume.
+
+  @param[in]  This             A pointer to the EFI_FILE_PROTOCOL instance that
+                               is the file handle the information is for.
+  @param[in]  InformationType  The type identifier for the information being set :
+                               EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+                               EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+  @param[in]  BufferSize       The size, in bytes, of Buffer.
+  @param[in]  Buffer           A pointer to the data buffer to write. The type of the
+                               data inside the buffer is indicated by InformationType.
+
+  @retval  EFI_SUCCESS            The information was set.
+  @retval  EFI_UNSUPPORTED        The InformationType is not known.
+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.
+  @retval  EFI_ACCESS_DENIED      An attempt is made to change the name of a file
+                                  to a file that is already present.
+  @retval  EFI_ACCESS_DENIED      An attempt is being made to change the
+                                  EFI_FILE_DIRECTORY Attribute.
+  @retval  EFI_ACCESS_DENIED      InformationType is EFI_FILE_INFO_ID and
+                                  the file was opened in read-only mode and an
+                                  attempt is being made to modify a field other
+                                  than Attribute.
+  @retval  EFI_WRITE_PROTECTED    An attempt is being made to modify a read-only
+                                  attribute.
+  @retval  EFI_BAD_BUFFER_SIZE    The size of the buffer is lower than that indicated by
+                                  the data inside the buffer.
+  @retval  EFI_OUT_OF_RESOURCES   A allocation needed to process the request failed.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsSetInfo (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN EFI_GUID           *InformationType,
+  IN UINTN              BufferSize,
+  IN VOID               *Buffer
+  );
+
+//
+// Directory API
+//
+
+EFI_STATUS
+BootMonFsOpenDirectory (
+  OUT EFI_FILE_PROTOCOL **NewHandle,
+  IN CHAR16             *FileName,
+  IN BOOTMON_FS_INSTANCE *Volume
+  );
+
+//
+// Internal API
+//
+
+/**
+  Search for a file given its name coded in Ascii.
+
+  When searching through the files of the volume, if a file is currently not
+  open, its name was written on the media and is kept in RAM in the
+  "HwDescription.Footer.Filename[]" field of the file's description.
+
+  If a file is currently open, its name might not have been written on the
+  media yet, and as the "HwDescription" is a mirror in RAM of what is on the
+  media the "HwDescription.Footer.Filename[]" might be outdated. In that case,
+  the up to date name of the file is stored in the "Info" field of the file's
+  description.
+
+  @param[in]   Instance       Pointer to the description of the volume in which
+                              the file has to be search for.
+  @param[in]   AsciiFileName  Name of the file.
+
+  @param[out]  File           Pointer to the description of the file if the
+                              file was found.
+
+  @retval  EFI_SUCCESS    The file was found.
+  @retval  EFI_NOT_FOUND  The file was not found.
+
+**/
+EFI_STATUS
+BootMonGetFileFromAsciiFileName (
+  IN  BOOTMON_FS_INSTANCE   *Instance,
+  IN  CHAR8*                AsciiFileName,
+  OUT BOOTMON_FS_FILE       **File
+  );
+
+EFI_STATUS
+BootMonGetFileFromPosition (
+  IN  BOOTMON_FS_INSTANCE   *Instance,
+  IN  UINTN                 Position,
+  OUT BOOTMON_FS_FILE       **File
+  );
+
+#endif
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c
new file mode 100644
index 000000000000..64ea0ec68048
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsDir.c
@@ -0,0 +1,766 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "BootMonFsInternal.h"
+
+EFIAPI
+EFI_STATUS
+OpenBootMonFsOpenVolume (
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+  OUT EFI_FILE_PROTOCOL              **Root
+  )
+{
+  BOOTMON_FS_INSTANCE *Instance;
+
+  Instance = BOOTMON_FS_FROM_FS_THIS (This);
+  if (Instance == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Instance->RootFile->Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
+
+  *Root = &Instance->RootFile->File;
+
+  return EFI_SUCCESS;
+}
+
+UINT32
+BootMonFsGetImageLength (
+  IN BOOTMON_FS_FILE      *File
+  )
+{
+  UINT32                   Index;
+  UINT32                   FileSize;
+  LIST_ENTRY              *RegionToFlushLink;
+  BOOTMON_FS_FILE_REGION  *Region;
+
+  FileSize = 0;
+
+  // Look at all Flash areas to determine file size
+  for (Index = 0; Index < HW_IMAGE_DESCRIPTION_REGION_MAX; Index++) {
+    FileSize += File->HwDescription.Region[Index].Size;
+  }
+
+  // Add the regions that have not been flushed yet
+  for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
+       !IsNull (&File->RegionToFlushLink, RegionToFlushLink);
+       RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink)
+       )
+  {
+    Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
+    if (Region->Offset + Region->Size > FileSize) {
+      FileSize += Region->Offset + Region->Size;
+    }
+  }
+
+  return FileSize;
+}
+
+UINTN
+BootMonFsGetPhysicalSize (
+  IN BOOTMON_FS_FILE* File
+  )
+{
+  // Return 0 for files that haven't yet been flushed to media
+  if (File->HwDescription.RegionCount == 0) {
+    return 0;
+  }
+
+  return ((File->HwDescription.BlockEnd - File->HwDescription.BlockStart) + 1 )
+          * File->Instance->Media->BlockSize;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsSetDirPosition (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN UINT64             Position
+  )
+{
+  BOOTMON_FS_FILE       *File;
+
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // UEFI Spec section 12.5:
+  // "The seek request for nonzero is not valid on open directories."
+  if (Position != 0) {
+    return EFI_UNSUPPORTED;
+  }
+  File->Position = Position;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BootMonFsOpenDirectory (
+  OUT EFI_FILE_PROTOCOL **NewHandle,
+  IN CHAR16             *FileName,
+  IN BOOTMON_FS_INSTANCE *Volume
+  )
+{
+  ASSERT(0);
+
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+GetFileSystemVolumeLabelInfo (
+  IN BOOTMON_FS_INSTANCE *Instance,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  )
+{
+  UINTN                         Size;
+  EFI_FILE_SYSTEM_VOLUME_LABEL *Label;
+  EFI_STATUS                    Status;
+
+  Label = Buffer;
+
+  // Value returned by StrSize includes null terminator.
+  Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
+         + StrSize (Instance->FsInfo.VolumeLabel);
+
+  if (*BufferSize >= Size) {
+    CopyMem (&Label->VolumeLabel, &Instance->FsInfo.VolumeLabel, Size);
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_BUFFER_TOO_SMALL;
+  }
+  *BufferSize = Size;
+  return Status;
+}
+
+// Helper function that calculates a rough "free space" by:
+// - Taking the media size
+// - Subtracting the sum of all file sizes
+// - Subtracting the block size times the number of files
+//    (To account for the blocks containing the HW_IMAGE_INFO
+STATIC
+UINT64
+ComputeFreeSpace (
+  IN BOOTMON_FS_INSTANCE *Instance
+  )
+{
+  LIST_ENTRY   *FileLink;
+  UINT64        FileSizeSum;
+  UINT64        MediaSize;
+  UINTN         NumFiles;
+  EFI_BLOCK_IO_MEDIA *Media;
+  BOOTMON_FS_FILE *File;
+
+  Media = Instance->BlockIo->Media;
+  MediaSize = Media->BlockSize * (Media->LastBlock + 1);
+
+  NumFiles = 0;
+  FileSizeSum = 0;
+  for (FileLink = GetFirstNode (&Instance->RootFile->Link);
+         !IsNull (&Instance->RootFile->Link, FileLink);
+         FileLink = GetNextNode (&Instance->RootFile->Link, FileLink)
+         )
+  {
+    File = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);
+    FileSizeSum += BootMonFsGetImageLength (File);
+
+    NumFiles++;
+  }
+
+  return MediaSize - (FileSizeSum + (Media->BlockSize + NumFiles));
+}
+
+STATIC
+EFI_STATUS
+GetFilesystemInfo (
+  IN BOOTMON_FS_INSTANCE *Instance,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  )
+{
+  EFI_STATUS              Status;
+
+  if (*BufferSize >= Instance->FsInfo.Size) {
+    Instance->FsInfo.FreeSpace = ComputeFreeSpace (Instance);
+    CopyMem (Buffer, &Instance->FsInfo, Instance->FsInfo.Size);
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_BUFFER_TOO_SMALL;
+  }
+
+  *BufferSize = Instance->FsInfo.Size;
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+GetFileInfo (
+  IN BOOTMON_FS_INSTANCE  *Instance,
+  IN BOOTMON_FS_FILE      *File,
+  IN OUT UINTN            *BufferSize,
+  OUT VOID                *Buffer
+  )
+{
+  EFI_FILE_INFO  *Info;
+  UINTN          ResultSize;
+
+  ResultSize = SIZE_OF_EFI_FILE_INFO + StrSize (File->Info->FileName);
+
+  if (*BufferSize < ResultSize) {
+    *BufferSize = ResultSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  Info = Buffer;
+
+  CopyMem (Info, File->Info, ResultSize);
+  // Size of the information
+  Info->Size = ResultSize;
+
+  *BufferSize = ResultSize;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetBootMonFsFileInfo (
+  IN BOOTMON_FS_INSTANCE *Instance,
+  IN BOOTMON_FS_FILE     *File,
+  IN OUT UINTN           *BufferSize,
+  OUT VOID               *Buffer
+  )
+{
+  EFI_STATUS             Status;
+  BOOTMON_FS_FILE_INFO   *Info;
+  UINTN                  ResultSize;
+  UINTN                  Index;
+
+  if (File == Instance->RootFile) {
+    Status = EFI_UNSUPPORTED;
+  } else {
+    ResultSize = SIZE_OF_BOOTMON_FS_FILE_INFO;
+
+    if (*BufferSize < ResultSize) {
+      *BufferSize = ResultSize;
+      Status = EFI_BUFFER_TOO_SMALL;
+    } else {
+      Info = Buffer;
+
+      // Zero out the structure
+      ZeroMem (Info, ResultSize);
+
+      // Fill in the structure
+      Info->Size = ResultSize;
+
+      Info->EntryPoint  = File->HwDescription.EntryPoint;
+      Info->RegionCount = File->HwDescription.RegionCount;
+      for (Index = 0; Index < File->HwDescription.RegionCount; Index++) {
+        Info->Region[Index].LoadAddress = File->HwDescription.Region[Index].LoadAddress;
+        Info->Region[Index].Size        = File->HwDescription.Region[Index].Size;
+        Info->Region[Index].Offset      = File->HwDescription.Region[Index].Offset;
+        Info->Region[Index].Checksum    = File->HwDescription.Region[Index].Checksum;
+      }
+      *BufferSize = ResultSize;
+      Status = EFI_SUCCESS;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Set the name of a file.
+
+  This is a helper function for SetFileInfo().
+
+  @param[in]  Instance  A pointer to the description of the volume
+                        the file belongs to.
+  @param[in]  File      A pointer to the description of the file.
+  @param[in]  FileName  A pointer to the new name of the file.
+
+  @retval  EFI_SUCCESS        The name was set.
+  @retval  EFI_ACCESS_DENIED  An attempt is made to change the name of a file
+                              to a file that is already present.
+
+**/
+STATIC
+EFI_STATUS
+SetFileName (
+  IN  BOOTMON_FS_INSTANCE  *Instance,
+  IN  BOOTMON_FS_FILE      *File,
+  IN  CONST CHAR16         *FileName
+  )
+{
+  CHAR8            AsciiFileName[MAX_NAME_LENGTH];
+  BOOTMON_FS_FILE  *SameFile;
+
+  // If the file path start with a \ strip it. The EFI Shell may
+  // insert a \ in front of the file name.
+  if (FileName[0] == L'\\') {
+    FileName++;
+  }
+
+  UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH);
+
+  if (BootMonGetFileFromAsciiFileName (
+        File->Instance,
+        AsciiFileName,
+        &SameFile
+        ) != EFI_NOT_FOUND) {
+    // A file with that name already exists.
+    return EFI_ACCESS_DENIED;
+  } else {
+    // OK, change the filename.
+    AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName,
+      (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16));
+    return EFI_SUCCESS;
+  }
+}
+
+/**
+  Set the size of a file.
+
+  This is a helper function for SetFileInfo().
+
+  @param[in]  Instance  A pointer to the description of the volume
+                        the file belongs to.
+  @param[in]  File      A pointer to the description of the file.
+  @param[in]  NewSize   The requested new size for the file.
+
+  @retval  EFI_SUCCESS           The size was set.
+  @retval  EFI_OUT_OF_RESOURCES  An allocation needed to process the request failed.
+
+**/
+STATIC
+EFI_STATUS
+SetFileSize (
+  IN BOOTMON_FS_INSTANCE  *Instance,
+  IN BOOTMON_FS_FILE      *BootMonFsFile,
+  IN UINTN                 NewSize
+  )
+{
+  EFI_STATUS              Status;
+  UINT32                  OldSize;
+  LIST_ENTRY              *RegionToFlushLink;
+  LIST_ENTRY              *NextRegionToFlushLink;
+  BOOTMON_FS_FILE_REGION  *Region;
+  EFI_FILE_PROTOCOL       *File;
+  CHAR8                   *Buffer;
+  UINTN                   BufferSize;
+  UINT64                  StoredPosition;
+
+  OldSize = BootMonFsFile->Info->FileSize;
+
+  //
+  // In case of file truncation, force the regions waiting for writing to
+  // not overflow the new size of the file.
+  //
+  if (NewSize < OldSize) {
+    for (RegionToFlushLink = GetFirstNode (&BootMonFsFile->RegionToFlushLink);
+         !IsNull (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);
+         )
+    {
+      NextRegionToFlushLink = GetNextNode (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);
+      Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
+      if (Region->Offset > NewSize) {
+        RemoveEntryList (RegionToFlushLink);
+        FreePool (Region->Buffer);
+        FreePool (Region);
+      } else {
+        Region->Size = MIN (Region->Size, NewSize - Region->Offset);
+      }
+      RegionToFlushLink = NextRegionToFlushLink;
+    }
+
+  } else if (NewSize > OldSize) {
+    // Increasing a file's size is potentially complicated as it may require
+    // moving the image description on media. The simplest way to do it is to
+    // seek past the end of the file (which is valid in UEFI) and perform a
+    // Write.
+    File = &BootMonFsFile->File;
+
+    // Save position
+    Status = File->GetPosition (File, &StoredPosition);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    // Set position at the end of the file
+    Status = File->SetPosition (File, OldSize);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    BufferSize = NewSize - OldSize;
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    Status = File->Write (File, &BufferSize, Buffer);
+    FreePool (Buffer);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    // Restore saved position
+    Status = File->SetPosition (File, StoredPosition);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  BootMonFsFile->Info->FileSize = NewSize;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set information about a file.
+
+  @param[in]  Instance  A pointer to the description of the volume
+                        the file belongs to.
+  @param[in]  File      A pointer to the description of the file.
+  @param[in]  Info      A pointer to the file information to write.
+
+  @retval  EFI_SUCCESS           The information was set.
+  @retval  EFI_ACCESS_DENIED     An attempt is being made to change the
+                                 EFI_FILE_DIRECTORY Attribute.
+  @retval  EFI_ACCESS_DENIED     The file was opened in read-only mode and an
+                                 attempt is being made to modify a field other
+                                 than Attribute.
+  @retval  EFI_ACCESS_DENIED     An attempt is made to change the name of a file
+                                 to a file that is already present.
+  @retval  EFI_WRITE_PROTECTED   An attempt is being made to modify a read-only
+                                 attribute.
+  @retval  EFI_OUT_OF_RESOURCES  An allocation needed to process the request
+                                 failed.
+
+**/
+STATIC
+EFI_STATUS
+SetFileInfo (
+  IN BOOTMON_FS_INSTANCE  *Instance,
+  IN BOOTMON_FS_FILE      *File,
+  IN EFI_FILE_INFO        *Info
+  )
+{
+  EFI_STATUS  Status;
+  BOOLEAN     FileSizeIsDifferent;
+  BOOLEAN     FileNameIsDifferent;
+  BOOLEAN     TimeIsDifferent;
+
+  //
+  // A directory can not be changed to a file and a file can
+  // not be changed to a directory.
+  //
+  if ((Info->Attribute & EFI_FILE_DIRECTORY)      !=
+      (File->Info->Attribute & EFI_FILE_DIRECTORY)  ) {
+    return EFI_ACCESS_DENIED;
+  }
+
+  FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize);
+  FileNameIsDifferent = (StrnCmp (
+                           Info->FileName,
+                           File->Info->FileName,
+                           MAX_NAME_LENGTH - 1
+                           ) != 0);
+  //
+  // Check if the CreateTime, LastAccess or ModificationTime
+  // have been changed. The file system does not support file
+  // timestamps thus the three times in "File->Info" are
+  // always equal to zero. The following comparison actually
+  // checks if all three times are still equal to 0 or not.
+  //
+  TimeIsDifferent = CompareMem (
+                      &Info->CreateTime,
+                      &File->Info->CreateTime,
+                      3 * sizeof (EFI_TIME)
+                      ) != 0;
+
+  //
+  // For a file opened in read-only mode, only the Attribute field can be
+  // modified. The root directory open mode is forced to read-only at opening
+  // thus the following test protects the root directory to be somehow modified.
+  //
+  if (File->OpenMode == EFI_FILE_MODE_READ) {
+    if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) {
+      return EFI_ACCESS_DENIED;
+    }
+  }
+
+  if (TimeIsDifferent) {
+    return EFI_WRITE_PROTECTED;
+  }
+
+  if (FileSizeIsDifferent) {
+    Status = SetFileSize (Instance, File, Info->FileSize);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  //
+  // Note down in RAM the Attribute field but we can not
+  // ask to store it in flash for the time being.
+  //
+  File->Info->Attribute = Info->Attribute;
+
+  if (FileNameIsDifferent) {
+    Status = SetFileName (Instance, File, Info->FileName);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsGetInfo (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN EFI_GUID           *InformationType,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  )
+{
+  EFI_STATUS           Status;
+  BOOTMON_FS_FILE     *File;
+  BOOTMON_FS_INSTANCE *Instance;
+
+  if ((This == NULL)                         ||
+      (InformationType == NULL)              ||
+      (BufferSize == NULL)                   ||
+      ((Buffer == NULL) && (*BufferSize > 0))  ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Instance = File->Instance;
+
+  // If the instance has not been initialized yet then do it ...
+  if (!Instance->Initialized) {
+    Status = BootMonFsInitialize (Instance);
+  } else {
+    Status = EFI_SUCCESS;
+  }
+
+  if (!EFI_ERROR (Status)) {
+    if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)
+        != 0) {
+      Status = GetFileSystemVolumeLabelInfo (Instance, BufferSize, Buffer);
+    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
+      Status = GetFilesystemInfo (Instance, BufferSize, Buffer);
+    } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
+      Status = GetFileInfo (Instance, File, BufferSize, Buffer);
+    } else if (CompareGuid (InformationType, &gArmBootMonFsFileInfoGuid) != 0) {
+      Status = GetBootMonFsFileInfo (Instance, File, BufferSize, Buffer);
+    } else {
+      Status = EFI_UNSUPPORTED;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Set information about a file or a volume.
+
+  @param[in]  This             A pointer to the EFI_FILE_PROTOCOL instance that
+                               is the file handle the information is for.
+  @param[in]  InformationType  The type identifier for the information being set :
+                               EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+                               EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+  @param[in]  BufferSize       The size, in bytes, of Buffer.
+  @param[in]  Buffer           A pointer to the data buffer to write. The type of the
+                               data inside the buffer is indicated by InformationType.
+
+  @retval  EFI_SUCCESS            The information was set.
+  @retval  EFI_UNSUPPORTED        The InformationType is not known.
+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.
+  @retval  EFI_ACCESS_DENIED      An attempt is made to change the name of a file
+                                  to a file that is already present.
+  @retval  EFI_ACCESS_DENIED      An attempt is being made to change the
+                                  EFI_FILE_DIRECTORY Attribute.
+  @retval  EFI_ACCESS_DENIED      InformationType is EFI_FILE_INFO_ID and
+                                  the file was opened in read-only mode and an
+                                  attempt is being made to modify a field other
+                                  than Attribute.
+  @retval  EFI_WRITE_PROTECTED    An attempt is being made to modify a read-only
+                                  attribute.
+  @retval  EFI_BAD_BUFFER_SIZE    The size of the buffer is lower than that indicated by
+                                  the data inside the buffer.
+  @retval  EFI_OUT_OF_RESOURCES   A allocation needed to process the request failed.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsSetInfo (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN EFI_GUID           *InformationType,
+  IN UINTN              BufferSize,
+  IN VOID               *Buffer
+  )
+{
+  BOOTMON_FS_FILE       *File;
+  EFI_FILE_INFO         *Info;
+  EFI_FILE_SYSTEM_INFO  *SystemInfo;
+
+  if ((This == NULL)            ||
+      (InformationType == NULL) ||
+      (Buffer == NULL)             ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+    Info = Buffer;
+    if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {
+      return EFI_INVALID_PARAMETER;
+    }
+    if (BufferSize < Info->Size) {
+      return EFI_BAD_BUFFER_SIZE;
+    }
+    return (SetFileInfo (File->Instance, File, Info));
+  }
+
+  //
+  // The only writable field in the other two information types
+  // (i.e. EFI_FILE_SYSTEM_INFO and EFI_FILE_SYSTEM_VOLUME_LABEL) is the
+  // filesystem volume label. This can be retrieved with GetInfo, but it is
+  // hard-coded into this driver, not stored on media.
+  //
+
+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+    SystemInfo = Buffer;
+    if (SystemInfo->Size <
+        (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {
+      return EFI_INVALID_PARAMETER;
+    }
+    if (BufferSize < SystemInfo->Size) {
+      return EFI_BAD_BUFFER_SIZE;
+    }
+    return EFI_WRITE_PROTECTED;
+  }
+
+  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+    return EFI_WRITE_PROTECTED;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsReadDirectory (
+  IN EFI_FILE_PROTOCOL    *This,
+  IN OUT UINTN            *BufferSize,
+  OUT VOID                *Buffer
+  )
+{
+  BOOTMON_FS_INSTANCE *Instance;
+  BOOTMON_FS_FILE     *RootFile;
+  BOOTMON_FS_FILE     *File;
+  EFI_FILE_INFO       *Info;
+  UINTN               NameSize;
+  UINTN               ResultSize;
+  EFI_STATUS          Status;
+  UINTN               Index;
+
+  RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (RootFile == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Instance = RootFile->Instance;
+  Status = BootMonGetFileFromPosition (Instance, RootFile->Position, &File);
+  if (EFI_ERROR (Status)) {
+    // No more file
+    *BufferSize = 0;
+    return EFI_SUCCESS;
+  }
+
+  NameSize   = AsciiStrLen (File->HwDescription.Footer.Filename) + 1;
+  ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16));
+  if (*BufferSize < ResultSize) {
+    *BufferSize = ResultSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // Zero out the structure
+  Info = Buffer;
+  ZeroMem (Info, ResultSize);
+
+  // Fill in the structure
+  Info->Size         = ResultSize;
+  Info->FileSize     = BootMonFsGetImageLength (File);
+  Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
+  for (Index = 0; Index < NameSize; Index++) {
+    Info->FileName[Index] = File->HwDescription.Footer.Filename[Index];
+  }
+
+  *BufferSize = ResultSize;
+  RootFile->Position++;
+
+  return EFI_SUCCESS;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsFlushDirectory (
+  IN EFI_FILE_PROTOCOL  *This
+  )
+{
+  BOOTMON_FS_FILE *RootFile;
+  LIST_ENTRY      *ListFiles;
+  LIST_ENTRY      *Link;
+  BOOTMON_FS_FILE *File;
+
+  RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (RootFile == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ListFiles = &RootFile->Link;
+
+  if (IsListEmpty (ListFiles)) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Flush all the files that need to be flushed
+  //
+
+  // Go through all the list of files to flush them
+  for (Link = GetFirstNode (ListFiles);
+       !IsNull (ListFiles, Link);
+       Link = GetNextNode (ListFiles, Link)
+       )
+  {
+    File = BOOTMON_FS_FILE_FROM_LINK_THIS (Link);
+    File->File.Flush (&File->File);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c
new file mode 100644
index 000000000000..a1150856f6ba
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsEntryPoint.c
@@ -0,0 +1,529 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DriverBinding.h>
+
+#include "BootMonFsInternal.h"
+
+EFI_DEVICE_PATH* mBootMonFsSupportedDevicePaths;
+LIST_ENTRY       mInstances;
+
+EFI_FILE_PROTOCOL mBootMonFsRootTemplate = {
+  EFI_FILE_PROTOCOL_REVISION,
+  BootMonFsOpenFile,
+  BootMonFsCloseFile,
+  BootMonFsDeleteFail,
+  BootMonFsReadDirectory,
+  BootMonFsWriteFile,
+  BootMonFsGetPositionUnsupported,  // UEFI Spec: GetPosition not valid on dirs
+  BootMonFsSetDirPosition,
+  BootMonFsGetInfo,
+  BootMonFsSetInfo,
+  BootMonFsFlushDirectory
+};
+
+EFI_FILE_PROTOCOL mBootMonFsFileTemplate = {
+  EFI_FILE_PROTOCOL_REVISION,
+  BootMonFsOpenFile,
+  BootMonFsCloseFile,
+  BootMonFsDelete,
+  BootMonFsReadFile,
+  BootMonFsWriteFile,
+  BootMonFsGetPosition,
+  BootMonFsSetPosition,
+  BootMonFsGetInfo,
+  BootMonFsSetInfo,
+  BootMonFsFlushFile
+};
+
+/**
+  Search for a file given its name coded in Ascii.
+
+  When searching through the files of the volume, if a file is currently not
+  open, its name was written on the media and is kept in RAM in the
+  "HwDescription.Footer.Filename[]" field of the file's description.
+
+  If a file is currently open, its name might not have been written on the
+  media yet, and as the "HwDescription" is a mirror in RAM of what is on the
+  media the "HwDescription.Footer.Filename[]" might be outdated. In that case,
+  the up to date name of the file is stored in the "Info" field of the file's
+  description.
+
+  @param[in]   Instance       Pointer to the description of the volume in which
+                              the file has to be search for.
+  @param[in]   AsciiFileName  Name of the file.
+
+  @param[out]  File           Pointer to the description of the file if the
+                              file was found.
+
+  @retval  EFI_SUCCESS    The file was found.
+  @retval  EFI_NOT_FOUND  The file was not found.
+
+**/
+EFI_STATUS
+BootMonGetFileFromAsciiFileName (
+  IN  BOOTMON_FS_INSTANCE   *Instance,
+  IN  CHAR8*                AsciiFileName,
+  OUT BOOTMON_FS_FILE       **File
+  )
+{
+  LIST_ENTRY       *Entry;
+  BOOTMON_FS_FILE  *FileEntry;
+  CHAR8            OpenFileAsciiFileName[MAX_NAME_LENGTH];
+  CHAR8            *AsciiFileNameToCompare;
+
+  // Go through all the files in the list and return the file handle
+  for (Entry = GetFirstNode (&Instance->RootFile->Link);
+       !IsNull (&Instance->RootFile->Link, Entry);
+       Entry = GetNextNode (&Instance->RootFile->Link, Entry)
+       )
+  {
+    FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);
+    if (FileEntry->Info != NULL) {
+      UnicodeStrToAsciiStrS (FileEntry->Info->FileName, OpenFileAsciiFileName,
+        MAX_NAME_LENGTH);
+      AsciiFileNameToCompare = OpenFileAsciiFileName;
+    } else {
+      AsciiFileNameToCompare = FileEntry->HwDescription.Footer.Filename;
+    }
+
+    if (AsciiStrCmp (AsciiFileNameToCompare, AsciiFileName) == 0) {
+      *File = FileEntry;
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+BootMonGetFileFromPosition (
+  IN  BOOTMON_FS_INSTANCE   *Instance,
+  IN  UINTN                 Position,
+  OUT BOOTMON_FS_FILE       **File
+  )
+{
+  LIST_ENTRY        *Entry;
+  BOOTMON_FS_FILE   *FileEntry;
+
+  // Go through all the files in the list and return the file handle
+  for (Entry = GetFirstNode (&Instance->RootFile->Link);
+       !IsNull (&Instance->RootFile->Link, Entry) && (&Instance->RootFile->Link != Entry);
+       Entry = GetNextNode (&Instance->RootFile->Link, Entry)
+       )
+  {
+    if (Position == 0) {
+      FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);
+      *File = FileEntry;
+      return EFI_SUCCESS;
+    }
+    Position--;
+  }
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+BootMonFsCreateFile (
+  IN  BOOTMON_FS_INSTANCE *Instance,
+  OUT BOOTMON_FS_FILE     **File
+  )
+{
+  BOOTMON_FS_FILE *NewFile;
+
+  NewFile = (BOOTMON_FS_FILE*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE));
+  if (NewFile == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  NewFile->Signature = BOOTMON_FS_FILE_SIGNATURE;
+  InitializeListHead (&NewFile->Link);
+  InitializeListHead (&NewFile->RegionToFlushLink);
+  NewFile->Instance = Instance;
+
+  // If the created file is the root file then create a directory EFI_FILE_PROTOCOL
+  if (Instance->RootFile == *File) {
+    CopyMem (&NewFile->File, &mBootMonFsRootTemplate, sizeof (mBootMonFsRootTemplate));
+  } else {
+    CopyMem (&NewFile->File, &mBootMonFsFileTemplate, sizeof (mBootMonFsFileTemplate));
+  }
+  *File = NewFile;
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SupportedDevicePathsInit (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  CHAR16*                             DevicePathListStr;
+  CHAR16*                             DevicePathStr;
+  CHAR16*                             NextDevicePathStr;
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
+  EFI_DEVICE_PATH_PROTOCOL           *Instance;
+
+  Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  // Initialize Variable
+  DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths);
+  mBootMonFsSupportedDevicePaths = NULL;
+
+  // Extract the Device Path instances from the multi-device path string
+  while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) {
+    NextDevicePathStr = StrStr (DevicePathListStr, L";");
+    if (NextDevicePathStr == NULL) {
+      DevicePathStr = DevicePathListStr;
+      DevicePathListStr = NULL;
+    } else {
+      DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr);
+      if (DevicePathStr == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0';
+      DevicePathListStr = NextDevicePathStr;
+      if (DevicePathListStr[0] == L';') {
+        DevicePathListStr++;
+      }
+    }
+
+    Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);
+    ASSERT (Instance != NULL);
+    mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance);
+
+    if (NextDevicePathStr != NULL) {
+      FreePool (DevicePathStr);
+    }
+    FreePool (Instance);
+  }
+
+  if (mBootMonFsSupportedDevicePaths == NULL) {
+    return EFI_UNSUPPORTED;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+EFI_STATUS
+EFIAPI
+BootMonFsDriverSupported (
+  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+  IN        EFI_HANDLE                   ControllerHandle,
+  IN        EFI_DEVICE_PATH_PROTOCOL    *DevicePath OPTIONAL
+  )
+{
+  EFI_DISK_IO_PROTOCOL  *DiskIo;
+  EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;
+  EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePaths;
+  EFI_STATUS Status;
+  UINTN Size1;
+  UINTN Size2;
+
+  //
+  // Open the IO Abstraction(s) needed to perform the supported test
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Close the I/O Abstraction(s) used to perform the supported test
+  //
+  gBS->CloseProtocol (
+         ControllerHandle,
+         &gEfiDiskIoProtocolGuid,
+         gImageHandle,
+         ControllerHandle
+         );
+
+  // Check that BlockIo protocol instance exists
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  NULL,
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Check if a DevicePath is attached to the handle
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **)&DevicePathProtocol,
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Check if the Device Path is the one which contains the Boot Monitor File System
+  Size1 = GetDevicePathSize (DevicePathProtocol);
+
+  // Go through the list of Device Path Instances
+  Status = EFI_UNSUPPORTED;
+  SupportedDevicePaths = mBootMonFsSupportedDevicePaths;
+  while (SupportedDevicePaths != NULL) {
+    SupportedDevicePath = GetNextDevicePathInstance (&SupportedDevicePaths, &Size2);
+
+    if ((Size1 == Size2) && (CompareMem (DevicePathProtocol, SupportedDevicePath, Size1) == 0)) {
+      // The Device Path is supported
+      Status = EFI_SUCCESS;
+      break;
+    }
+  }
+
+  gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, gImageHandle, ControllerHandle);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+BootMonFsDriverStart (
+  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+  IN        EFI_HANDLE                   ControllerHandle,
+  IN        EFI_DEVICE_PATH_PROTOCOL    *DevicePath OPTIONAL
+  )
+{
+  BOOTMON_FS_INSTANCE *Instance;
+  EFI_STATUS           Status;
+  UINTN                VolumeNameSize;
+  EFI_FILE_INFO       *Info;
+
+  Instance = AllocateZeroPool (sizeof (BOOTMON_FS_INSTANCE));
+  if (Instance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Initialize the BlockIo of the Instance
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **)&(Instance->BlockIo),
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **)&(Instance->DiskIo),
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  //
+  // Initialize the attributes of the Instance
+  //
+  Instance->Signature = BOOTMON_FS_SIGNATURE;
+  Instance->ControllerHandle = ControllerHandle;
+  Instance->Media = Instance->BlockIo->Media;
+  Instance->Binding = DriverBinding;
+
+    // Initialize the Simple File System Protocol
+  Instance->Fs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
+  Instance->Fs.OpenVolume = OpenBootMonFsOpenVolume;
+
+  // Volume name + L' ' + '2' digit number
+  VolumeNameSize = StrSize (BOOTMON_FS_VOLUME_LABEL) + (3 * sizeof (CHAR16));
+
+  // Initialize FileSystem Information
+  Instance->FsInfo.Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + VolumeNameSize;
+  Instance->FsInfo.BlockSize = Instance->Media->BlockSize;
+  Instance->FsInfo.ReadOnly = FALSE;
+  Instance->FsInfo.VolumeSize =
+    Instance->Media->BlockSize * (Instance->Media->LastBlock - Instance->Media->LowestAlignedLba);
+  CopyMem (Instance->FsInfo.VolumeLabel, BOOTMON_FS_VOLUME_LABEL, StrSize (BOOTMON_FS_VOLUME_LABEL));
+
+  // Initialize the root file
+  Status = BootMonFsCreateFile (Instance, &Instance->RootFile);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  Info = AllocateZeroPool (sizeof (EFI_FILE_INFO));
+  if (Info == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Error;
+  }
+  Instance->RootFile->Info = Info;
+
+  // Initialize the DevicePath of the Instance
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **)&(Instance->DevicePath),
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  //
+  // Install the Simple File System Protocol
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                      &ControllerHandle,
+                      &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,
+                      NULL
+                      );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  InsertTailList (&mInstances, &Instance->Link);
+
+  return EFI_SUCCESS;
+
+Error:
+
+    if (Instance->RootFile != NULL) {
+      if (Instance->RootFile->Info != NULL) {
+        FreePool (Instance->RootFile->Info);
+      }
+      FreePool (Instance->RootFile);
+    }
+    FreePool (Instance);
+
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+BootMonFsDriverStop (
+  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+  IN        EFI_HANDLE                   ControllerHandle,
+  IN        UINTN                        NumberOfChildren,
+  IN        EFI_HANDLE                  *ChildHandleBuffer OPTIONAL
+  )
+{
+  BOOTMON_FS_INSTANCE *Instance;
+  LIST_ENTRY          *Link;
+  EFI_STATUS           Status;
+  BOOLEAN              InstanceFound;
+
+  // Find instance from ControllerHandle.
+  Instance = NULL;
+  InstanceFound = FALSE;
+  // For each instance in mInstances:
+  for (Link = GetFirstNode (&mInstances); !IsNull (&mInstances, Link); Link = GetNextNode (&mInstances, Link)) {
+    Instance = BOOTMON_FS_FROM_LINK (Link);
+
+    if (Instance->ControllerHandle == ControllerHandle) {
+      InstanceFound = TRUE;
+      break;
+    }
+  }
+  ASSERT (InstanceFound == TRUE);
+
+  gBS->CloseProtocol (
+      ControllerHandle,
+      &gEfiDevicePathProtocolGuid,
+      DriverBinding->ImageHandle,
+      ControllerHandle);
+
+  gBS->CloseProtocol (
+      ControllerHandle,
+      &gEfiDiskIoProtocolGuid,
+      DriverBinding->ImageHandle,
+      ControllerHandle);
+
+  gBS->CloseProtocol (
+      ControllerHandle,
+      &gEfiBlockIoProtocolGuid,
+      DriverBinding->ImageHandle,
+      ControllerHandle);
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+      &ControllerHandle,
+      &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,
+      NULL);
+
+  FreePool (Instance->RootFile->Info);
+  FreePool (Instance->RootFile);
+  FreePool (Instance);
+
+  return Status;
+}
+
+//
+// Simple Network Protocol Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL mBootMonFsDriverBinding = {
+  BootMonFsDriverSupported,
+  BootMonFsDriverStart,
+  BootMonFsDriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+EFI_STATUS
+EFIAPI
+BootMonFsEntryPoint (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  InitializeListHead (&mInstances);
+
+  // Initialize the list of Device Paths that could support BootMonFs
+  Status = SupportedDevicePathsInit ();
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &ImageHandle,
+                    &gEfiDriverBindingProtocolGuid, &mBootMonFsDriverBinding,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    DEBUG((EFI_D_ERROR,"Warning: No Device Paths supporting BootMonFs have been defined in the PCD.\n"));
+  }
+
+  return Status;
+}
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h b/Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h
new file mode 100644
index 000000000000..c1bef755aea0
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsHw.h
@@ -0,0 +1,57 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __BOOTMON_FS_HW_H__
+#define __BOOTMON_FS_HW_H__
+
+#define MAX_NAME_LENGTH 32
+
+#define HW_IMAGE_FOOTER_SIGNATURE_1 0x464C5348
+#define HW_IMAGE_FOOTER_SIGNATURE_2 0x464F4F54
+
+#define HW_IMAGE_FOOTER_VERSION     1
+#define HW_IMAGE_FOOTER_OFFSET      92
+
+#define HW_IMAGE_FOOTER_VERSION2    2
+#define HW_IMAGE_FOOTER_OFFSET2     96
+
+typedef struct {
+  CHAR8  Filename[MAX_NAME_LENGTH];
+  UINT32 Offset;
+  UINT32 Version;
+  UINT32 FooterSignature1;
+  UINT32 FooterSignature2;
+} HW_IMAGE_FOOTER;
+
+#define HW_IMAGE_DESCRIPTION_REGION_MAX 4
+
+// This structure is located at the end of a block when a file is present
+typedef struct {
+  UINT32  EntryPoint;
+  UINT32  Attributes;
+  UINT32  RegionCount;
+  struct {
+    UINT32 LoadAddress;
+    UINT32 Size;
+    UINT32 Offset;
+    UINT32 Checksum;
+  } Region[HW_IMAGE_DESCRIPTION_REGION_MAX];
+  UINT32  BlockStart;
+  UINT32  BlockEnd;
+  UINT32  FooterChecksum;
+
+  HW_IMAGE_FOOTER Footer;
+} HW_IMAGE_DESCRIPTION;
+
+#endif
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c
new file mode 100644
index 000000000000..346c360292eb
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsImages.c
@@ -0,0 +1,222 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/NorFlashPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Protocol/SimpleFileSystem.h>
+
+#include "BootMonFsInternal.h"
+
+UINT32
+BootMonFsChecksum (
+  IN VOID   *Data,
+  IN UINT32 Size
+  )
+{
+  UINT32  *Ptr;
+  UINT32  Word;
+  UINT32  Checksum;
+
+  ASSERT (Size % 4 == 0);
+
+  Checksum = 0;
+  Ptr = (UINT32*)Data;
+
+  while (Size > 0) {
+    Word = *Ptr++;
+    Size -= 4;
+
+    if (Word > ~Checksum) {
+      Checksum++;
+    }
+
+    Checksum += Word;
+  }
+
+  return ~Checksum;
+}
+
+EFI_STATUS
+BootMonFsComputeFooterChecksum (
+  IN OUT HW_IMAGE_DESCRIPTION *Footer
+  )
+{
+  HW_IMAGE_DESCRIPTION *Description;
+  UINT32                Index;
+
+  Footer->Attributes = 1;
+
+  Description = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION));
+  if (Description == NULL) {
+    DEBUG ((DEBUG_ERROR, "BootMonFsComputeFooterChecksum: Unable to allocate memory.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Copy over to temporary shim
+  CopyMem (Description, Footer, sizeof (HW_IMAGE_DESCRIPTION));
+
+  // BootMon doesn't checksum the previous checksum
+  Description->FooterChecksum = 0;
+
+  // Blank out regions which aren't being used.
+  for (Index = Footer->RegionCount; Index < HW_IMAGE_DESCRIPTION_REGION_MAX; Index++) {
+    Description->Region[Index].Checksum = 0;
+    Description->Region[Index].LoadAddress = 0;
+    Description->Region[Index].Offset = 0;
+    Description->Region[Index].Size = 0;
+  }
+
+  // Compute the checksum
+  Footer->FooterChecksum = BootMonFsChecksum (Description, sizeof (HW_IMAGE_DESCRIPTION));
+
+  FreePool (Description);
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+BootMonFsIsImageValid (
+  IN HW_IMAGE_DESCRIPTION  *Desc,
+  IN EFI_LBA                Lba
+  )
+{
+  EFI_STATUS            Status;
+  HW_IMAGE_FOOTER      *Footer;
+  UINT32                Checksum;
+
+  Footer = &Desc->Footer;
+
+  // Check that the verification bytes are present
+  if ((Footer->FooterSignature1 != HW_IMAGE_FOOTER_SIGNATURE_1) ||
+      (Footer->FooterSignature2 != HW_IMAGE_FOOTER_SIGNATURE_2)) {
+    return FALSE;
+  }
+
+  if (Footer->Version == HW_IMAGE_FOOTER_VERSION) {
+    if (Footer->Offset != HW_IMAGE_FOOTER_OFFSET) {
+      return FALSE;
+    }
+  } else if (Footer->Version == HW_IMAGE_FOOTER_VERSION2) {
+    if (Footer->Offset != HW_IMAGE_FOOTER_OFFSET2) {
+      return FALSE;
+    }
+  } else {
+    return FALSE;
+  }
+
+  Checksum = Desc->FooterChecksum;
+  Status = BootMonFsComputeFooterChecksum (Desc);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Warning: failed to compute checksum for image '%a'\n", Desc->Footer.Filename));
+  }
+
+  if (Desc->FooterChecksum != Checksum) {
+    DEBUG ((DEBUG_ERROR, "Warning: image '%a' checksum mismatch.\n", Desc->Footer.Filename));
+  }
+
+  if ((Desc->BlockEnd != Lba) || (Desc->BlockStart > Desc->BlockEnd)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+STATIC
+EFI_STATUS
+BootMonFsDiscoverNextImage (
+  IN     BOOTMON_FS_INSTANCE      *Instance,
+  IN OUT EFI_LBA                  *LbaStart,
+  IN OUT BOOTMON_FS_FILE          *File
+  )
+{
+  EFI_DISK_IO_PROTOCOL  *DiskIo;
+  EFI_LBA                CurrentLba;
+  UINT64                 DescOffset;
+  EFI_STATUS             Status;
+
+  DiskIo = Instance->DiskIo;
+
+  CurrentLba = *LbaStart;
+
+  // Look for images in the rest of this block
+  while (CurrentLba <= Instance->Media->LastBlock) {
+    // Work out the byte offset into media of the image description in this block
+    // If present, the image description is at the very end of the block.
+    DescOffset = ((CurrentLba + 1) * Instance->Media->BlockSize) - sizeof (HW_IMAGE_DESCRIPTION);
+
+    // Read the image description from media
+    Status = DiskIo->ReadDisk (DiskIo,
+                       Instance->Media->MediaId,
+                       DescOffset,
+                       sizeof (HW_IMAGE_DESCRIPTION),
+                       &File->HwDescription
+                       );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    // If we found a valid image description...
+    if (BootMonFsIsImageValid (&File->HwDescription, (CurrentLba - Instance->Media->LowestAlignedLba))) {
+      DEBUG ((EFI_D_ERROR, "Found image: %a in block %d.\n",
+        &(File->HwDescription.Footer.Filename),
+        (UINTN)(CurrentLba - Instance->Media->LowestAlignedLba)
+        ));
+      File->HwDescAddress = DescOffset;
+
+      *LbaStart = CurrentLba + 1;
+      return EFI_SUCCESS;
+    } else {
+      CurrentLba++;
+    }
+  }
+
+  *LbaStart = CurrentLba;
+  return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+BootMonFsInitialize (
+  IN BOOTMON_FS_INSTANCE *Instance
+  )
+{
+  EFI_STATUS               Status;
+  EFI_LBA                  Lba;
+  UINT32                   ImageCount;
+  BOOTMON_FS_FILE          *NewFile;
+
+  ImageCount = 0;
+  Lba = 0;
+
+  while (1) {
+    Status = BootMonFsCreateFile (Instance, &NewFile);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Status = BootMonFsDiscoverNextImage (Instance, &Lba, NewFile);
+    if (EFI_ERROR (Status)) {
+      // Free NewFile allocated by BootMonFsCreateFile ()
+      FreePool (NewFile);
+      break;
+    }
+    InsertTailList (&Instance->RootFile->Link, &NewFile->Link);
+    ImageCount++;
+  }
+
+  Instance->Initialized = TRUE;
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h b/Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h
new file mode 100644
index 000000000000..c0c6599cb707
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsInternal.h
@@ -0,0 +1,101 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __BOOTMONFS_INTERNAL_H__
+#define __BOOTMONFS_INTERNAL_H__
+
+#include <PiDxe.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Guid/BootMonFsFileInfo.h>
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+#include <Guid/FileSystemVolumeLabelInfo.h>
+
+#include "BootMonFsHw.h"
+
+#define BOOTMON_FS_VOLUME_LABEL   L"NOR Flash"
+
+typedef struct _BOOTMON_FS_INSTANCE BOOTMON_FS_INSTANCE;
+
+typedef struct {
+  LIST_ENTRY            Link;
+  VOID*                 Buffer;
+  UINTN                 Size;
+  UINT64                Offset; // Offset from the start of the file
+} BOOTMON_FS_FILE_REGION;
+
+typedef struct {
+  UINT32                Signature;
+  LIST_ENTRY            Link;
+  BOOTMON_FS_INSTANCE   *Instance;
+
+  UINTN                 HwDescAddress;
+  HW_IMAGE_DESCRIPTION  HwDescription;
+
+  EFI_FILE_PROTOCOL     File;
+
+  //
+  // The following fields are relevant only if the file is open.
+  //
+
+  EFI_FILE_INFO         *Info;
+  UINT64                Position;
+  // If the file needs to be flushed then this list contain the memory
+  // buffer that creates this file
+  LIST_ENTRY            RegionToFlushLink;
+  UINT64                OpenMode;
+} BOOTMON_FS_FILE;
+
+#define BOOTMON_FS_FILE_SIGNATURE              SIGNATURE_32('b', 'o', 't', 'f')
+#define BOOTMON_FS_FILE_FROM_FILE_THIS(a)      CR (a, BOOTMON_FS_FILE, File, BOOTMON_FS_FILE_SIGNATURE)
+#define BOOTMON_FS_FILE_FROM_LINK_THIS(a)      CR (a, BOOTMON_FS_FILE, Link, BOOTMON_FS_FILE_SIGNATURE)
+
+struct _BOOTMON_FS_INSTANCE {
+  UINT32                               Signature;
+  EFI_HANDLE                           ControllerHandle;
+
+  LIST_ENTRY                           Link;
+
+  EFI_DRIVER_BINDING_PROTOCOL         *Binding;
+  EFI_DISK_IO_PROTOCOL                *DiskIo;
+  EFI_BLOCK_IO_PROTOCOL               *BlockIo;
+  EFI_BLOCK_IO_MEDIA                  *Media;
+  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
+
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL      Fs;
+
+  EFI_FILE_SYSTEM_INFO                 FsInfo;
+  CHAR16                               Label[20];
+
+  BOOTMON_FS_FILE                     *RootFile; // All the other files are linked to this root
+  BOOLEAN                              Initialized;
+};
+
+#define BOOTMON_FS_SIGNATURE            SIGNATURE_32('b', 'o', 't', 'm')
+#define BOOTMON_FS_FROM_FS_THIS(a)      CR (a, BOOTMON_FS_INSTANCE, Fs, BOOTMON_FS_SIGNATURE)
+#define BOOTMON_FS_FROM_LINK(a)         CR (a, BOOTMON_FS_INSTANCE, Link, BOOTMON_FS_SIGNATURE)
+
+#include "BootMonFsApi.h"
+
+#endif
+
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c
new file mode 100644
index 000000000000..ae10055255ff
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsOpenClose.c
@@ -0,0 +1,795 @@
+/** @file
+*
+*  Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "BootMonFsInternal.h"
+
+// Clear a file's image description on storage media:
+// UEFI allows you to seek past the end of a file, a subsequent write will grow
+// the file. It does not specify how space between the former end of the file
+// and the beginning of the write should be filled. It's therefore possible that
+// BootMonFs metadata, that comes after the end of a file, could be left there
+// and wrongly detected by BootMonFsImageInBlock.
+STATIC
+EFI_STATUS
+InvalidateImageDescription (
+  IN  BOOTMON_FS_FILE  *File
+  )
+{
+  EFI_DISK_IO_PROTOCOL   *DiskIo;
+  EFI_BLOCK_IO_PROTOCOL  *BlockIo;
+  UINT32                  MediaId;
+  VOID                   *Buffer;
+  EFI_STATUS              Status;
+
+  DiskIo = File->Instance->DiskIo;
+  BlockIo = File->Instance->BlockIo;
+  MediaId = BlockIo->Media->MediaId;
+
+  Buffer = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION));
+
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = DiskIo->WriteDisk (DiskIo,
+                    MediaId,
+                    File->HwDescAddress,
+                    sizeof (HW_IMAGE_DESCRIPTION),
+                    Buffer
+                    );
+
+  FreePool(Buffer);
+
+  return Status;
+}
+
+/**
+  Write the description of a file to storage media.
+
+  This function uses DiskIo to write to the media, so call BlockIo->FlushBlocks()
+  after calling it to ensure the data are written on the media.
+
+  @param[in]  File       Description of the file whose description on the
+                         storage media has to be updated.
+  @param[in]  FileName   Name of the file. Its length is assumed to be
+                         lower than MAX_NAME_LENGTH.
+  @param[in]  DataSize   Number of data bytes of the file.
+  @param[in]  FileStart  File's starting position on media. FileStart must
+                         be aligned to the media's block size.
+
+  @retval  EFI_WRITE_PROTECTED  The device cannot be written to.
+  @retval  EFI_DEVICE_ERROR     The device reported an error while performing
+                                the write operation.
+
+**/
+STATIC
+EFI_STATUS
+WriteFileDescription (
+  IN  BOOTMON_FS_FILE  *File,
+  IN  CHAR8            *FileName,
+  IN  UINT32            DataSize,
+  IN  UINT64            FileStart
+  )
+{
+  EFI_STATUS            Status;
+  EFI_DISK_IO_PROTOCOL  *DiskIo;
+  UINTN                 BlockSize;
+  UINT32                FileSize;
+  HW_IMAGE_DESCRIPTION  *Description;
+
+  DiskIo    = File->Instance->DiskIo;
+  BlockSize = File->Instance->BlockIo->Media->BlockSize;
+  ASSERT (FileStart % BlockSize == 0);
+
+  //
+  // Construct the file description
+  //
+
+  FileSize = DataSize + sizeof (HW_IMAGE_DESCRIPTION);
+  Description = &File->HwDescription;
+  Description->Attributes = 1;
+  Description->BlockStart = FileStart / BlockSize;
+  Description->BlockEnd   = Description->BlockStart + (FileSize / BlockSize);
+  AsciiStrCpyS (Description->Footer.Filename,
+    sizeof Description->Footer.Filename, FileName);
+
+#ifdef MDE_CPU_ARM
+  Description->Footer.Offset  = HW_IMAGE_FOOTER_OFFSET;
+  Description->Footer.Version = HW_IMAGE_FOOTER_VERSION;
+#else
+  Description->Footer.Offset  = HW_IMAGE_FOOTER_OFFSET2;
+  Description->Footer.Version = HW_IMAGE_FOOTER_VERSION2;
+#endif
+  Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1;
+  Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2;
+  Description->RegionCount = 1;
+  Description->Region[0].Checksum = 0;
+  Description->Region[0].Offset = Description->BlockStart * BlockSize;
+  Description->Region[0].Size = DataSize;
+
+  Status = BootMonFsComputeFooterChecksum (Description);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  File->HwDescAddress = ((Description->BlockEnd + 1) * BlockSize) - sizeof (HW_IMAGE_DESCRIPTION);
+
+  // Update the file description on the media
+  Status = DiskIo->WriteDisk (
+                    DiskIo,
+                    File->Instance->Media->MediaId,
+                    File->HwDescAddress,
+                    sizeof (HW_IMAGE_DESCRIPTION),
+                    Description
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+// Find a space on media for a file that has not yet been flushed to disk.
+// Just returns the first space that's big enough.
+// This function could easily be adapted to:
+// - Find space for moving an existing file that has outgrown its space
+//   (We do not currently move files, just return EFI_VOLUME_FULL)
+// - Find space for a fragment of a file that has outgrown its space
+//   (We do not currently fragment files - it's not clear whether fragmentation
+//    is actually part of BootMonFs as there is no spec)
+// - Be more clever about finding space (choosing the largest or smallest
+//   suitable space)
+// Parameters:
+// File - the new (not yet flushed) file for which we need to find space.
+// FileStart - the position on media of the file (in bytes).
+STATIC
+EFI_STATUS
+BootMonFsFindSpaceForNewFile (
+  IN  BOOTMON_FS_FILE     *File,
+  IN  UINT64              FileSize,
+  OUT UINT64              *FileStart
+  )
+{
+  LIST_ENTRY              *FileLink;
+  BOOTMON_FS_FILE         *RootFile;
+  BOOTMON_FS_FILE         *FileEntry;
+  UINTN                    BlockSize;
+  EFI_BLOCK_IO_MEDIA      *Media;
+
+  Media = File->Instance->BlockIo->Media;
+  BlockSize = Media->BlockSize;
+  RootFile = File->Instance->RootFile;
+
+  // This function must only be called for file which has not been flushed into
+  // Flash yet
+  ASSERT (File->HwDescription.RegionCount == 0);
+
+  *FileStart = 0;
+  // Go through all the files in the list
+  for (FileLink = GetFirstNode (&RootFile->Link);
+         !IsNull (&RootFile->Link, FileLink);
+         FileLink = GetNextNode (&RootFile->Link, FileLink)
+         )
+  {
+    FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);
+    // Skip files that aren't on disk yet
+    if (FileEntry->HwDescription.RegionCount == 0) {
+      continue;
+    }
+
+    // If the free space preceding the file is big enough to contain the new
+    // file then use it!
+    if (((FileEntry->HwDescription.BlockStart * BlockSize) - *FileStart)
+        >= FileSize) {
+      // The file list must be in disk-order
+      RemoveEntryList (&File->Link);
+      File->Link.BackLink = FileLink->BackLink;
+      File->Link.ForwardLink = FileLink;
+      FileLink->BackLink->ForwardLink = &File->Link;
+      FileLink->BackLink = &File->Link;
+
+      return EFI_SUCCESS;
+    } else {
+      *FileStart = (FileEntry->HwDescription.BlockEnd + 1) * BlockSize;
+    }
+  }
+  // See if there's space after the last file
+  if ((((Media->LastBlock + 1) * BlockSize) - *FileStart) >= FileSize) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_VOLUME_FULL;
+  }
+}
+
+// Free the resources in the file's Region list.
+STATIC
+VOID
+FreeFileRegions (
+  IN  BOOTMON_FS_FILE *File
+  )
+{
+  LIST_ENTRY              *RegionToFlushLink;
+  BOOTMON_FS_FILE_REGION  *Region;
+
+  RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
+  while (!IsNull (&File->RegionToFlushLink, RegionToFlushLink)) {
+    // Repeatedly remove the first node from the list and free its resources.
+    Region = (BOOTMON_FS_FILE_REGION *) RegionToFlushLink;
+    RemoveEntryList (RegionToFlushLink);
+    FreePool (Region->Buffer);
+    FreePool (Region);
+
+    RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
+  }
+}
+
+/**
+  Flush all modified data associated with a file to a device.
+
+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the
+                    file handle to flush.
+
+  @retval  EFI_SUCCESS            The data was flushed.
+  @retval  EFI_ACCESS_DENIED      The file was opened read-only.
+  @retval  EFI_DEVICE_ERROR       The device reported an error.
+  @retval  EFI_VOLUME_FULL        The volume is full.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to flush the data.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsFlushFile (
+  IN EFI_FILE_PROTOCOL  *This
+  )
+{
+  EFI_STATUS               Status;
+  BOOTMON_FS_INSTANCE     *Instance;
+  EFI_FILE_INFO           *Info;
+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;
+  EFI_BLOCK_IO_MEDIA      *Media;
+  EFI_DISK_IO_PROTOCOL    *DiskIo;
+  UINTN                    BlockSize;
+  CHAR8                    AsciiFileName[MAX_NAME_LENGTH];
+  LIST_ENTRY              *RegionToFlushLink;
+  BOOTMON_FS_FILE         *File;
+  BOOTMON_FS_FILE         *NextFile;
+  BOOTMON_FS_FILE_REGION  *Region;
+  LIST_ENTRY              *FileLink;
+  UINTN                    CurrentPhysicalSize;
+  UINT64                   FileStart;
+  UINT64                   FileEnd;
+  UINT64                   RegionStart;
+  UINT64                   RegionEnd;
+  UINT64                   NewDataSize;
+  UINT64                   NewFileSize;
+  UINT64                   EndOfAppendSpace;
+  BOOLEAN                  HasSpace;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (File->OpenMode == EFI_FILE_MODE_READ) {
+    return EFI_ACCESS_DENIED;
+  }
+
+  Instance  = File->Instance;
+  Info      = File->Info;
+  BlockIo   = Instance->BlockIo;
+  Media     = BlockIo->Media;
+  DiskIo    = Instance->DiskIo;
+  BlockSize = Media->BlockSize;
+
+  UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, MAX_NAME_LENGTH);
+
+  // If the file doesn't exist then find a space for it
+  if (File->HwDescription.RegionCount == 0) {
+    Status = BootMonFsFindSpaceForNewFile (
+               File,
+               Info->FileSize + sizeof (HW_IMAGE_DESCRIPTION),
+               &FileStart
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  } else {
+    FileStart = File->HwDescription.BlockStart * BlockSize;
+  }
+  // FileEnd is the current NOR address of the end of the file's data
+  FileEnd = FileStart + File->HwDescription.Region[0].Size;
+
+  for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
+       !IsNull (&File->RegionToFlushLink, RegionToFlushLink);
+       RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink)
+       )
+  {
+    Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
+    if (Region->Size == 0) {
+      continue;
+    }
+
+    // RegionStart and RegionEnd are the the intended NOR address of the
+    // start and end of the region
+    RegionStart = FileStart   + Region->Offset;
+    RegionEnd   = RegionStart + Region->Size;
+
+    if (RegionEnd < FileEnd) {
+      // Handle regions representing edits to existing portions of the file
+      // Write the region data straight into the file
+      Status = DiskIo->WriteDisk (DiskIo,
+                        Media->MediaId,
+                        RegionStart,
+                        Region->Size,
+                        Region->Buffer
+                        );
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+    } else {
+      // Handle regions representing appends to the file
+      //
+      // Note: Since seeking past the end of the file with SetPosition() is
+      //  valid, it's possible there will be a gap between the current end of
+      //  the file and the beginning of the new region. Since the UEFI spec
+      //  says nothing about this case (except "a subsequent write would grow
+      //  the file"), we just leave garbage in the gap.
+
+      // Check if there is space to append the new region
+      HasSpace = FALSE;
+      NewDataSize = RegionEnd - FileStart;
+      NewFileSize = NewDataSize + sizeof (HW_IMAGE_DESCRIPTION);
+      CurrentPhysicalSize = BootMonFsGetPhysicalSize (File);
+      if (NewFileSize <= CurrentPhysicalSize) {
+        HasSpace = TRUE;
+      } else {
+        // Get the File Description for the next file
+        FileLink = GetNextNode (&Instance->RootFile->Link, &File->Link);
+        if (!IsNull (&Instance->RootFile->Link, FileLink)) {
+          NextFile = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);
+
+          // If there is space between the beginning of the current file and the
+          // beginning of the next file then use it
+          EndOfAppendSpace = NextFile->HwDescription.BlockStart * BlockSize;
+        } else {
+          // We are flushing the last file.
+          EndOfAppendSpace = (Media->LastBlock + 1) * BlockSize;
+        }
+        if (EndOfAppendSpace - FileStart >= NewFileSize) {
+          HasSpace = TRUE;
+        }
+      }
+
+      if (HasSpace == TRUE) {
+        // Invalidate the current image description of the file if any.
+        if (File->HwDescAddress != 0) {
+          Status = InvalidateImageDescription (File);
+          if (EFI_ERROR (Status)) {
+            return Status;
+          }
+        }
+
+        // Write the new file data
+        Status = DiskIo->WriteDisk (
+                    DiskIo,
+                    Media->MediaId,
+                    RegionStart,
+                    Region->Size,
+                    Region->Buffer
+                    );
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+
+        Status = WriteFileDescription (File, AsciiFileName, NewDataSize, FileStart);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+
+      } else {
+        // There isn't a space for the file.
+        // Options here are to move the file or fragment it. However as files
+        // may represent boot images at fixed positions, these options will
+        // break booting if the bootloader doesn't use BootMonFs to find the
+        // image.
+
+        return EFI_VOLUME_FULL;
+      }
+    }
+  }
+
+  FreeFileRegions (File);
+  Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
+
+  if ((AsciiStrCmp (AsciiFileName, File->HwDescription.Footer.Filename) != 0) ||
+      (Info->FileSize != File->HwDescription.Region[0].Size)               ) {
+    Status = WriteFileDescription (File, AsciiFileName, Info->FileSize, FileStart);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  // Flush DiskIo Buffers (see UEFI Spec 12.7 - DiskIo buffers are flushed by
+  // calling FlushBlocks on the same device's BlockIo).
+  BlockIo->FlushBlocks (BlockIo);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Close a specified file handle.
+
+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                    handle to close.
+
+  @retval  EFI_SUCCESS            The file was closed.
+  @retval  EFI_INVALID_PARAMETER  The parameter "This" is NULL or is not an open
+                                  file handle.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsCloseFile (
+  IN EFI_FILE_PROTOCOL  *This
+  )
+{
+  BOOTMON_FS_FILE  *File;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // In the case of a file and not the root directory
+  if (This != &File->Instance->RootFile->File) {
+    This->Flush (This);
+    FreePool (File->Info);
+    File->Info = NULL;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Open a file on the boot monitor file system.
+
+  The boot monitor file system does not allow for sub-directories. There is only
+  one directory, the root one. On any attempt to create a directory, the function
+  returns in error with the EFI_WRITE_PROTECTED error code.
+
+  @param[in]   This        A pointer to the EFI_FILE_PROTOCOL instance that is
+                           the file handle to source location.
+  @param[out]  NewHandle   A pointer to the location to return the opened
+                           handle for the new file.
+  @param[in]   FileName    The Null-terminated string of the name of the file
+                           to be opened.
+  @param[in]   OpenMode    The mode to open the file : Read or Read/Write or
+                           Read/Write/Create
+  @param[in]   Attributes  Attributes of the file in case of a file creation
+
+  @retval  EFI_SUCCESS            The file was open.
+  @retval  EFI_NOT_FOUND          The specified file could not be found or the specified
+                                  directory in which to create a file could not be found.
+  @retval  EFI_DEVICE_ERROR       The device reported an error.
+  @retval  EFI_WRITE_PROTECTED    Attempt to create a directory. This is not possible
+                                  with the Boot Monitor file system.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to open the file.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsOpenFile (
+  IN EFI_FILE_PROTOCOL   *This,
+  OUT EFI_FILE_PROTOCOL  **NewHandle,
+  IN CHAR16              *FileName,
+  IN UINT64              OpenMode,
+  IN UINT64              Attributes
+  )
+{
+  EFI_STATUS           Status;
+  BOOTMON_FS_FILE      *Directory;
+  BOOTMON_FS_FILE      *File;
+  BOOTMON_FS_INSTANCE  *Instance;
+  CHAR8                *Buf;
+  CHAR16               *Path;
+  CHAR16               *Separator;
+  CHAR8                *AsciiFileName;
+  EFI_FILE_INFO        *Info;
+  UINTN                AsciiFileNameSize;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (Directory->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((FileName == NULL) || (NewHandle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // The only valid modes are read, read/write, and read/write/create
+  //
+  if ( (OpenMode != EFI_FILE_MODE_READ) &&
+       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
+       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Instance = Directory->Instance;
+
+  //
+  // If the instance has not been initialized yet then do it ...
+  //
+  if (!Instance->Initialized) {
+    Status = BootMonFsInitialize (Instance);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  //
+  // Copy the file path to be able to work on it. We do not want to
+  // modify the input file name string "FileName".
+  //
+  Buf = AllocateCopyPool (StrSize (FileName), FileName);
+  if (Buf == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  Path = (CHAR16*)Buf;
+  AsciiFileName = NULL;
+  Info = NULL;
+
+  //
+  // Handle single periods, double periods and convert forward slashes '/'
+  // to backward '\' ones. Does not handle a '.' at the beginning of the
+  // path for the time being.
+  //
+  if (PathCleanUpDirectories (Path) == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Error;
+  }
+
+  //
+  // Detect if the first component of the path refers to a directory.
+  // This is done to return the correct error code when trying to
+  // access or create a directory other than the root directory.
+  //
+
+  //
+  // Search for the '\\' sequence and if found return in error
+  // with the EFI_INVALID_PARAMETER error code. ere in the path.
+  //
+  if (StrStr (Path, L"\\\\") != NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Error;
+  }
+  //
+  // Get rid of the leading '\' if any.
+  //
+  Path += (Path[0] == L'\\');
+
+  //
+  // Look for a '\' in the file path. If one is found then
+  // the first component of the path refers to a directory
+  // that is not the root directory.
+  //
+  Separator = StrStr (Path, L"\\");
+  if (Separator != NULL) {
+    //
+    // In the case '<dir name>\' and a creation, return
+    // EFI_WRITE_PROTECTED if this is for a directory
+    // creation, EFI_INVALID_PARAMETER otherwise.
+    //
+    if ((*(Separator + 1) == '\0') && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {
+      if (Attributes & EFI_FILE_DIRECTORY) {
+        Status = EFI_WRITE_PROTECTED;
+      } else {
+        Status = EFI_INVALID_PARAMETER;
+      }
+    } else {
+      //
+      // Attempt to open a file or a directory that is not in the
+      // root directory or to open without creation a directory
+      // located in the root directory, returns EFI_NOT_FOUND.
+      //
+      Status = EFI_NOT_FOUND;
+    }
+    goto Error;
+  }
+
+  //
+  // BootMonFs interface requires ASCII filenames
+  //
+  AsciiFileNameSize = StrLen (Path) + 1;
+  if (AsciiFileNameSize > MAX_NAME_LENGTH) {
+    AsciiFileNameSize = MAX_NAME_LENGTH;
+  }
+  AsciiFileName = AllocatePool (AsciiFileNameSize);
+  if (AsciiFileName == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Error;
+  }
+  UnicodeStrToAsciiStrS (Path, AsciiFileName, AsciiFileNameSize);
+
+  if ((AsciiFileName[0] == '\0') ||
+      (AsciiFileName[0] == '.' )    ) {
+    //
+    // Opening the root directory
+    //
+
+    *NewHandle = &Instance->RootFile->File;
+    Instance->RootFile->Position = 0;
+    Status = EFI_SUCCESS;
+  } else {
+
+    if ((OpenMode & EFI_FILE_MODE_CREATE) &&
+        (Attributes & EFI_FILE_DIRECTORY)    ) {
+      Status = EFI_WRITE_PROTECTED;
+      goto Error;
+    }
+
+    //
+    // Allocate a buffer to store the characteristics of the file while the
+    // file is open. We allocate the maximum size to not have to reallocate
+    // if the file name is changed.
+    //
+    Info = AllocateZeroPool (
+             SIZE_OF_EFI_FILE_INFO + (sizeof (CHAR16) * MAX_NAME_LENGTH));
+    if (Info == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Error;
+    }
+
+    //
+    // Open or create a file in the root directory.
+    //
+
+    Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File);
+    if (Status == EFI_NOT_FOUND) {
+      if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
+        goto Error;
+      }
+
+      Status = BootMonFsCreateFile (Instance, &File);
+      if (EFI_ERROR (Status)) {
+        goto Error;
+      }
+      InsertHeadList (&Instance->RootFile->Link, &File->Link);
+      Info->Attribute = Attributes;
+    } else {
+      //
+      // File already open, not supported yet.
+      //
+      if (File->Info != NULL) {
+        Status = EFI_UNSUPPORTED;
+        goto Error;
+      }
+    }
+
+    Info->FileSize     = BootMonFsGetImageLength (File);
+    Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
+    AsciiStrToUnicodeStrS (AsciiFileName, Info->FileName, MAX_NAME_LENGTH);
+
+    File->Info = Info;
+    Info = NULL;
+    File->Position = 0;
+    File->OpenMode = OpenMode;
+
+    *NewHandle = &File->File;
+  }
+
+Error:
+
+  FreePool (Buf);
+  if (AsciiFileName != NULL) {
+    FreePool (AsciiFileName);
+  }
+  if (Info != NULL) {
+    FreePool (Info);
+  }
+
+  return Status;
+}
+
+// Delete() for the root directory's EFI_FILE_PROTOCOL instance
+EFIAPI
+EFI_STATUS
+BootMonFsDeleteFail (
+  IN EFI_FILE_PROTOCOL *This
+  )
+{
+  This->Close(This);
+  // You can't delete the root directory
+  return EFI_WARN_DELETE_FAILURE;
+}
+
+/**
+  Close and delete a file from the boot monitor file system.
+
+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                    handle to delete.
+
+  @retval  EFI_SUCCESS              The file was closed and deleted.
+  @retval  EFI_INVALID_PARAMETER    The parameter "This" is NULL or is not an open
+                                    file handle.
+  @retval  EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsDelete (
+  IN EFI_FILE_PROTOCOL *This
+  )
+{
+  EFI_STATUS               Status;
+  BOOTMON_FS_FILE         *File;
+  LIST_ENTRY              *RegionToFlushLink;
+  BOOTMON_FS_FILE_REGION  *Region;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!IsListEmpty (&File->RegionToFlushLink)) {
+    // Free the entries from the Buffer List
+    RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
+    do {
+      Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
+
+      //
+      // Get next element of the list before deleting the region description
+      // that contain the LIST_ENTRY structure.
+      //
+      RegionToFlushLink = RemoveEntryList (RegionToFlushLink);
+
+      // Free the buffers
+      FreePool (Region->Buffer);
+      FreePool (Region);
+    } while (!IsListEmpty (&File->RegionToFlushLink));
+  }
+
+  // If (RegionCount is greater than 0) then the file already exists
+  if (File->HwDescription.RegionCount > 0) {
+    // Invalidate the last Block
+    Status = InvalidateImageDescription (File);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      return  EFI_WARN_DELETE_FAILURE;
+    }
+  }
+
+  // Remove the entry from the list
+  RemoveEntryList (&File->Link);
+  FreePool (File->Info);
+  FreePool (File);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c
new file mode 100644
index 000000000000..f8124e95ac0c
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsReadWrite.c
@@ -0,0 +1,259 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Protocol/SimpleFileSystem.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#include "BootMonFsInternal.h"
+
+/**
+  Read data from an open file.
+
+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that
+                              is the file handle to read data from.
+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the
+                              amount of data returned in Buffer. In both cases,
+                              the size is measured in bytes.
+  @param[out]     Buffer      The buffer into which the data is read.
+
+  @retval  EFI_SUCCESS            The data was read.
+  @retval  EFI_DEVICE_ERROR       On entry, the current file position is
+                                  beyond the end of the file, or the device
+                                  reported an error while performing the read
+                                  operation.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsReadFile (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN          *BufferSize,
+  OUT VOID              *Buffer
+  )
+{
+  BOOTMON_FS_INSTANCE   *Instance;
+  BOOTMON_FS_FILE       *File;
+  EFI_DISK_IO_PROTOCOL  *DiskIo;
+  EFI_BLOCK_IO_MEDIA    *Media;
+  UINT64                FileStart;
+  EFI_STATUS            Status;
+  UINTN                 RemainingFileSize;
+
+  if ((This == NULL)       ||
+      (BufferSize == NULL) ||
+      (Buffer == NULL)        ) {
+    return EFI_INVALID_PARAMETER;
+  }
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Ensure the file has been written in Flash before reading it.
+  // This keeps the code simple and avoids having to manage a non-flushed file.
+  BootMonFsFlushFile (This);
+
+  Instance  = File->Instance;
+  DiskIo    = Instance->DiskIo;
+  Media     = Instance->Media;
+  FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
+
+  if (File->Position >= File->Info->FileSize) {
+    // The entire file has been read or the position has been
+    // set past the end of the file.
+    *BufferSize = 0;
+    if (File->Position > File->Info->FileSize) {
+      return EFI_DEVICE_ERROR;
+    } else {
+      return EFI_SUCCESS;
+    }
+  }
+
+  // This driver assumes that the entire file is in region 0.
+  RemainingFileSize = File->Info->FileSize - File->Position;
+
+  // If read would go past end of file, truncate the read
+  if (*BufferSize > RemainingFileSize) {
+    *BufferSize = RemainingFileSize;
+  }
+
+  Status = DiskIo->ReadDisk (
+                    DiskIo,
+                    Media->MediaId,
+                    FileStart + File->Position,
+                    *BufferSize,
+                    Buffer
+                    );
+  if (EFI_ERROR (Status)) {
+    *BufferSize = 0;
+  }
+
+  File->Position += *BufferSize;
+
+  return Status;
+}
+
+/**
+  Write data to an open file.
+
+  The data is not written to the flash yet. It will be written when the file
+  will be either read, closed or flushed.
+
+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that
+                              is the file handle to write data to.
+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the
+                              size of the data actually written. In both cases,
+                              the size is measured in bytes.
+  @param[in]      Buffer      The buffer of data to write.
+
+  @retval  EFI_SUCCESS            The data was written.
+  @retval  EFI_ACCESS_DENIED      The file was opened read only.
+  @retval  EFI_OUT_OF_RESOURCES   Unable to allocate the buffer to store the
+                                  data to write.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsWriteFile (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN          *BufferSize,
+  IN VOID               *Buffer
+  )
+{
+  BOOTMON_FS_FILE         *File;
+  BOOTMON_FS_FILE_REGION  *Region;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (File->OpenMode == EFI_FILE_MODE_READ) {
+    return EFI_ACCESS_DENIED;
+  }
+
+  // Allocate and initialize the memory region
+  Region = (BOOTMON_FS_FILE_REGION*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE_REGION));
+  if (Region == NULL) {
+    *BufferSize = 0;
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Region->Buffer = AllocateCopyPool (*BufferSize, Buffer);
+  if (Region->Buffer == NULL) {
+    *BufferSize = 0;
+    FreePool (Region);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Region->Size   = *BufferSize;
+  Region->Offset = File->Position;
+
+  InsertTailList (&File->RegionToFlushLink, &Region->Link);
+
+  File->Position += *BufferSize;
+
+  if (File->Position > File->Info->FileSize) {
+    File->Info->FileSize = File->Position;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set a file's current position.
+
+  @param[in]  This      A pointer to the EFI_FILE_PROTOCOL instance that is
+                        the file handle to set the requested position on.
+  @param[in]  Position  The byte position from the start of the file to set.
+
+  @retval  EFI_SUCCESS            The position was set.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsSetPosition (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN UINT64             Position
+  )
+{
+  BOOTMON_FS_FILE  *File;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // UEFI Spec section 12.5:
+  // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
+  // be set to the end of the file."
+  //
+  if (Position == 0xFFFFFFFFFFFFFFFF) {
+    Position = File->Info->FileSize;
+  }
+
+  File->Position = Position;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Return a file's current position.
+
+  @param[in]   This      A pointer to the EFI_FILE_PROTOCOL instance that is
+                         the file handle to get the current position on.
+  @param[out]  Position  The address to return the file's current position value.
+
+  @retval  EFI_SUCCESS            The position was returned.
+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.
+
+**/
+EFIAPI
+EFI_STATUS
+BootMonFsGetPosition (
+  IN  EFI_FILE_PROTOCOL *This,
+  OUT UINT64            *Position
+  )
+{
+  BOOTMON_FS_FILE         *File;
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+  if (File->Info == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Position == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Position = File->Position;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c b/Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c
new file mode 100644
index 000000000000..4ecc4ea008ea
--- /dev/null
+++ b/Platform/ARM/Drivers/BootMonFs/BootMonFsUnsupported.c
@@ -0,0 +1,37 @@
+/** @file
+*
+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "BootMonFsInternal.h"
+
+EFIAPI
+EFI_STATUS
+BootMonFsSetPositionUnsupported (
+  IN EFI_FILE_PROTOCOL  *This,
+  IN UINT64             Position
+  )
+{
+  ASSERT(0);
+  return EFI_UNSUPPORTED;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsGetPositionUnsupported (
+  IN EFI_FILE_PROTOCOL  *This,
+  OUT UINT64            *Position
+  )
+{
+  ASSERT(0);
+  return EFI_UNSUPPORTED;
+}
diff --git a/Platform/ARM/Include/Guid/BootMonFsFileInfo.h b/Platform/ARM/Include/Guid/BootMonFsFileInfo.h
new file mode 100644
index 000000000000..c4d805c14f0e
--- /dev/null
+++ b/Platform/ARM/Include/Guid/BootMonFsFileInfo.h
@@ -0,0 +1,47 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+*  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __BOOTMON_FS_FILE_INFO_H__
+#define __BOOTMON_FS_FILE_INFO_H__
+
+#define BOOTMON_FS_FILE_INFO_ID \
+  { \
+    0x41e26b9c, 0xada6, 0x45b3, {0x80, 0x8e, 0x23, 0x57, 0xa3, 0x5b, 0x60, 0xd6 } \
+  }
+
+// From BootMonFS header file
+#define BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX 4
+
+typedef struct {
+  // The size of the structure.
+  UINT64    Size;
+
+  // Subset of properties stored in the file meta-data.
+  UINT32  EntryPoint;
+  UINT32  RegionCount;
+  struct {
+    UINT32 LoadAddress;
+    UINT32 Size;
+    UINT32 Offset;
+    UINT32 Checksum;
+  } Region[BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX];
+
+} BOOTMON_FS_FILE_INFO;
+
+#define SIZE_OF_BOOTMON_FS_FILE_INFO \
+  OFFSET_OF (BOOTMON_FS_FILE_INFO, Region[BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX - 1].Checksum)
+
+extern EFI_GUID gArmBootMonFsFileInfoGuid;
+
+#endif // __BOOTMON_FS_FILE_INFO_H__
diff --git a/Platform/ARM/Include/Library/ArmShellCmdLib.h b/Platform/ARM/Include/Library/ArmShellCmdLib.h
new file mode 100644
index 000000000000..eb31cd405338
--- /dev/null
+++ b/Platform/ARM/Include/Library/ArmShellCmdLib.h
@@ -0,0 +1,57 @@
+/** @file
+*
+*  Definitions for the Dynamic Shell command library
+*
+*  Copyright (C) 2014, ARM Ltd
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+*  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _ARM_SHELL_CMD_LIB_H_
+#define _ARM_SHELL_CMD_LIB_H_
+
+/**
+
+  Initialize and Install EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL for RunAxf command.
+
+  @param[in] ImageHandle        Handle the protocol should be attached to.
+
+  @retval EFI_SUCCESS           The command has been installed successfully.
+
+  @retval EFI_UNSUPPORTED       Help for the command failed to initialise.
+
+  @return                       Status code returned by InstallProtocolInterface
+                                Boot Service function.
+
+**/
+EFI_STATUS
+ShellDynCmdRunAxfInstall (
+  IN EFI_HANDLE             ImageHandle
+  );
+
+/**
+
+  Uninstall the RunAxf Command
+
+  @param[in] ImageHandle  Handle of the device where the protocol should have
+                          been installed.
+
+  @retval EFI_SUCCESS     The device has been un-initialized successfully.
+
+  @return                 Status code returned by UninstallProtocolInterface
+                          Boot Service function.
+
+**/
+EFI_STATUS
+ShellDynCmdRunAxfUninstall (
+  IN EFI_HANDLE             ImageHandle
+  );
+
+#endif // _ARM_SHELL_CMD_LIB_H_
diff --git a/Platform/ARM/JunoPkg/ArmJuno.dsc b/Platform/ARM/JunoPkg/ArmJuno.dsc
index 80a5ef631ce9..3cbacb35dae3 100644
--- a/Platform/ARM/JunoPkg/ArmJuno.dsc
+++ b/Platform/ARM/JunoPkg/ArmJuno.dsc
@@ -160,7 +160,7 @@ [PcdsFixedAtBuild.common]
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|24
 
   # List of Device Paths that support BootMonFs
-  gArmPlatformTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)"
+  gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)"
 
   #
   # ARM OS Loader
diff --git a/Platform/ARM/JunoPkg/ArmJuno.fdf b/Platform/ARM/JunoPkg/ArmJuno.fdf
index bb78e1fa8589..04d58323d130 100644
--- a/Platform/ARM/JunoPkg/ArmJuno.fdf
+++ b/Platform/ARM/JunoPkg/ArmJuno.fdf
@@ -135,7 +135,7 @@ [FV.FvMain]
   INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
 
   # Versatile Express FileSystem
-  INF ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+  INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
 
   #
   # FAT filesystem + GPT/MBR partitioning
diff --git a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
index b215a3bc882d..70175c2d2405 100644
--- a/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+++ b/Platform/ARM/JunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
@@ -28,6 +28,7 @@ [Packages]
   EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  Platform/ARM/ARM.dec
   Platform/ARM/JunoPkg/ArmJuno.dec
 
 [LibraryClasses]
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c
new file mode 100644
index 000000000000..67bbb9e86334
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.c
@@ -0,0 +1,95 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ArmShellCmdLib.h>
+
+#include "ArmShellCmdRunAxf.h"
+
+EFI_HANDLE gRunAxfHiiHandle = NULL;
+
+#define RUNAXF_HII_GUID \
+  { \
+  0xf5a6413b, 0x78d5, 0x448e, { 0xa2, 0x15, 0x22, 0x82, 0x8e, 0xbc, 0x61, 0x61 } \
+  }
+
+EFI_GUID gRunAxfHiiGuid = RUNAXF_HII_GUID;
+
+static EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolRunAxf = {
+    L"runaxf",                             // *CommandName
+    ShellDynCmdRunAxfHandler,              // Handler
+    ShellDynCmdRunAxfGetHelp               // GetHelp
+};
+
+EFI_STATUS
+ShellDynCmdRunAxfInstall (
+  IN EFI_HANDLE             ImageHandle
+  )
+{
+  EFI_STATUS Status;
+
+  // Register our shell command
+  Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+                 &gEfiShellDynamicCommandProtocolGuid,
+                 &mShellDynCmdProtocolRunAxf,
+                 NULL);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Load the manual page for our command
+  //
+  // 3rd parameter 'HII strings array' must be name of .uni strings file
+  // followed by 'Strings', e.g. mycommands.uni must be specified as
+  // 'mycommandsStrings' because the build Autogen process defines this as a
+  // string array for the strings in your .uni file.  Examine your Build folder
+  // under your package's DEBUG folder and you will find it defined in a
+  // xxxStrDefs.h file.
+  //
+  gRunAxfHiiHandle = HiiAddPackages (&gRunAxfHiiGuid, ImageHandle,
+                                     ArmShellCmdRunAxfStrings, NULL);
+  if (gRunAxfHiiHandle == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ShellDynCmdRunAxfUninstall (
+  IN EFI_HANDLE             ImageHandle
+  )
+{
+
+  EFI_STATUS Status;
+
+  if (gRunAxfHiiHandle != NULL) {
+    HiiRemovePackages (gRunAxfHiiHandle);
+  }
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+                 &gEfiShellDynamicCommandProtocolGuid,
+                 &mShellDynCmdProtocolRunAxf,
+                 NULL);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h
new file mode 100644
index 000000000000..2708b53cc172
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.h
@@ -0,0 +1,83 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __ARM_SHELL_CMD_RUNAXF__
+#define __ARM_SHELL_CMD_RUNAXF__
+
+#include <Protocol/Shell.h>
+#include <Protocol/ShellDynamicCommand.h>
+
+#include <Library/HiiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+extern EFI_GUID      gRunAxfHiiGuid;
+extern EFI_HANDLE    gRunAxfHiiHandle;
+extern EFI_HANDLE    gRunAxfImageHandle;
+
+// List of data segments to load to memory from AXF/ELF file.
+typedef struct {
+  LIST_ENTRY  Link;       // This attribute must be the first entry of this
+                          // structure (to avoid pointer computation)
+  UINTN       MemOffset;  // Where the data should go, Dest
+  UINTN       FileOffset; // Where the data is from, Src
+  BOOLEAN     Zeroes;     // A section of Zeroes. Like .bss in ELF
+  UINTN       Length;     // Number of bytes.
+} RUNAXF_LOAD_LIST;
+
+
+/**
+  This is the shell command handler function pointer callback type. 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 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 EFI_SUCCESS         The operation was successful.
+  @return other               The operation failed.
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdRunAxfHandler (
+  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 command help handler function pointer callback type. This
+  function is responsible for displaying help information for the associated
+  command.
+
+  @param[in] This             The instance of the
+                              EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in] Language         The pointer to the language string to use.
+
+  @return string              Pool allocated help string, must be freed by
+                              caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdRunAxfGetHelp (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL    *This,
+  IN CONST CHAR8                           *Language
+  );
+
+#endif //__ARM_SHELL_CMD_RUNAXF__
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf
new file mode 100644
index 000000000000..8473b0fa90d2
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf
@@ -0,0 +1,54 @@
+## @file
+#
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = ArmShellCmdRunAxf
+  FILE_GUID                      = 676a0e7c-2e16-43e8-b49c-d82a1f9e24df
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmShellCmdRunAxfLib
+
+[Sources.common]
+  ArmShellCmdRunAxf.c
+  ArmShellCmdRunAxf.uni
+  RunAxf.c
+  BootMonFsLoader.h
+  BootMonFsLoader.c
+  ElfLoader.h
+  ElfLoader.c
+  # ELF definitions taken from BaseTools
+  elf32.h
+  elf64.h
+  elf_common.h
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/ARM/ARM.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  DebugLib
+  HiiLib
+  ShellLib
+
+[Protocols]
+  gEfiShellDynamicCommandProtocolGuid
+
+[Guids]
+  gArmBootMonFsFileInfoGuid
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni
new file mode 100644
index 000000000000..6b7296079175
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.uni
@@ -0,0 +1,68 @@
+// *++
+//
+// Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+//
+// This program and the accompanying materials are licensed and made available
+// under the terms and conditions of the BSD License which accompanies this
+// distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// Module Name:
+//
+//   RunAxfStrings.uni
+//
+// Abstract:
+//
+//   String definitions for the Shell 'runaxf' command
+//
+// Revision History:
+//
+// --*/
+
+/=#
+
+#langdef   en-US "English"
+
+#string STR_RUNAXF_BAD_FILE        #language en-US  "File type not supported\n"
+#string STR_RUNAXF_BAD_ARCH        #language en-US  "Architecture not supported\n"
+#string STR_RUNAXF_INVALID_ARG     #language en-US  "Invalid argument(s)\n"
+#string STR_RUNAXF_FILE_NOT_FOUND  #language en-US  "File not found : %s\n"
+#string STR_RUNAXF_NO_MEM          #language en-US  "Out of Memory\n"
+#string STR_RUNAXF_READ_FAIL       #language en-US  "Failed to read file\n"
+
+#string STR_RUNAXF_ELFMAGIC        #language en-US  "Wrong magic number. The file is either not an ELF binary or it is corrupted.\n"
+#string STR_RUNAXF_ELFNOTEXEC      #language en-US  "Wrong ELF file type, expected an executable file.\n"
+#string STR_RUNAXF_ELFNOPROG       #language en-US  "No program header table found in ELF file.\n"
+#string STR_RUNAXF_ELFWRONGCLASS   #language en-US  "Invalid ELF Class type.\n"
+#string STR_RUNAXF_ELFBADFORMAT    #language en-US  "ELF file format is incorrect (filesize > memorysize).\n"
+#string STR_RUNAXF_ELFBADHEADER    #language en-US  "Invalid ELF header.\n"
+#string STR_RUNAXF_ELFFAILSEG      #language en-US  "Failed to load segment from ELF file.\n
+#string STR_RUNAXF_ELFNOSEG        #language en-US  "The ELF file must have at least 1 loadable segment.\n"
+
+#string STR_RUNAXF_ELFWRONGCLASS_32  #language en-US  "Wrong file class, expected 32-bit ELF file.\n"
+#string STR_RUNAXF_ELFWRONGCLASS_64  #language en-US  "Wrong file class, expected 64-bit ELF file.\n"
+#string STR_RUNAXF_ELFWRONGMACH_32   #language en-US  "Wrong machine type, expected ARM.\n"
+#string STR_RUNAXF_ELFWRONGMACH_64   #language en-US  "Wrong machine type, expected AARCH64.\n"
+
+#string STR_GET_HELP_RUNAXF        #language en-US ""
+".TH runaxf 0 "load and execute AXF binary"\r\n"
+".SH NAME\r\n"
+"Loads and executes ARM Executable File (AXF).\r\n"
+".SH SYNOPSIS\r\n"
+"runaxf file\r\n"
+".SH OPTIONS\r\n"
+"file        AXF binary to load and execute.\r\n"
+".SH DESCRIPTION\r\n"
+"Loads and executes ARM Executable File (AXF). This function is not expected to return.\r\n"
+
+".SH RETURNVALUES\r\n"
+"SHELL_DEVICE_ERROR       The operation failed to complete.\r\n"
+"SHELL_INVALID_PARAMETER  One of the passed in parameters was incorrectly formatted or its value was out of bounds.\r\n"
+"SHELL_UNSUPPORTED        The action as requested was unsupported.\r\n"
+"SHELL_OUT_OF_RESOURCES   There was insufficient free space for the request to be completed.\r\n"
+".SH EXAMPLES\r\n"
+"  fs0:\> runaxf file.axf\r\n"
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c
new file mode 100644
index 000000000000..0bce037dcb08
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.c
@@ -0,0 +1,154 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+*  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <Guid/BootMonFsFileInfo.h>
+#include <Protocol/SimpleFileSystem.h> // EFI_FILE_HANDLE
+
+#include "ArmShellCmdRunAxf.h"
+#include "BootMonFsLoader.h"
+
+/**
+  Check that loading the file is supported.
+
+  Not all information is checked, only the properties that matters to us in
+  our simplified loader.
+
+  BootMonFS file properties is not in a file header but in the file-system
+  metadata, so we need to pass a handle to the file to allow access to the
+  information.
+
+  @param[in] FileHandle  Handle of the file to check.
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the header is invalid.
+  @retval EFI_UNSUPPORTED if the file type/platform is not supported.
+**/
+EFI_STATUS
+BootMonFsCheckFile (
+  IN  CONST EFI_FILE_HANDLE  FileHandle
+  )
+{
+  EFI_STATUS           Status;
+  BOOTMON_FS_FILE_INFO Info;
+  UINTN                InfoSize;
+  UINTN                Index;
+
+  ASSERT (FileHandle != NULL);
+
+  // Try to load the file information as BootMonFS executable.
+  InfoSize = sizeof (Info);
+  // Get BootMon File info and see if it gives us what we need to load the file.
+  Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid,
+                               &InfoSize, &Info);
+
+  if (!EFI_ERROR (Status)) {
+    // Check the values return to see if they look reasonable.
+    // Do we have a good entrypoint and at least one good load region?
+    // We assume here that we cannot load to address 0x0.
+    if ((Info.Size == 0) || (Info.EntryPoint == 0) || (Info.RegionCount == 0) ||
+        (Info.RegionCount > BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX)) {
+      // The file does not seem to be of the right type.
+      Status = EFI_UNSUPPORTED;
+    } else {
+      // Check load regions. We just check for valid numbers, we dont do the
+      // checksums. Info.Offset can be zero if it loads from the start of the
+      // file.
+      for (Index = 0; Index < Info.RegionCount; Index++) {
+        if ((Info.Region[Index].LoadAddress == 0) || (Info.Region[Index].Size == 0)) {
+          Status = EFI_UNSUPPORTED;
+          break;
+        }
+      }
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Load a binary file from BootMonFS.
+
+  @param[in]  FileHandle    Handle of the file to load.
+
+  @param[in]  FileData      Address  of the file data in memory.
+
+  @param[out] EntryPoint    Will be filled with the ELF entry point address.
+
+  @param[out] ImageSize     Will be filled with the file size in memory. This
+                            will effectively be equal to the sum of the load
+                            region sizes.
+
+  This function assumes the file is valid and supported as checked with
+  BootMonFsCheckFile().
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the file is invalid.
+**/
+EFI_STATUS
+BootMonFsLoadFile (
+  IN  CONST EFI_FILE_HANDLE   FileHandle,
+  IN  CONST VOID             *FileData,
+  OUT VOID                  **EntryPoint,
+  OUT LIST_ENTRY             *LoadList
+  )
+{
+  EFI_STATUS            Status;
+  BOOTMON_FS_FILE_INFO  Info;
+  UINTN                 InfoSize;
+  UINTN                 Index;
+  UINTN                 ImageSize;
+  RUNAXF_LOAD_LIST     *LoadNode;
+
+  ASSERT (FileHandle != NULL);
+  ASSERT (FileData   != NULL);
+  ASSERT (EntryPoint != NULL);
+  ASSERT (LoadList   != NULL);
+
+  ImageSize = 0;
+
+  InfoSize = sizeof (Info);
+  Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid,
+                               &InfoSize, &Info);
+
+  if (!EFI_ERROR (Status)) {
+    *EntryPoint = (VOID*)((UINTN)Info.EntryPoint);
+    // Load all the regions to run-time memory
+    for (Index = 0; Index < Info.RegionCount; Index++) {
+      LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
+      if (LoadNode == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        break;
+      }
+
+      LoadNode->MemOffset  = (UINTN)Info.Region[Index].LoadAddress;
+      LoadNode->FileOffset = (UINTN)FileData + Info.Region[Index].Offset;
+      LoadNode->Length     = (UINTN)Info.Region[Index].Size;
+      InsertTailList (LoadList, &LoadNode->Link);
+
+      ImageSize += LoadNode->Length;
+    }
+  }
+
+  if ((!EFI_ERROR (Status)) && (ImageSize == 0)) {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h
new file mode 100644
index 000000000000..de3c0adcd11f
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/BootMonFsLoader.h
@@ -0,0 +1,66 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Ltd. All rights reserved.
+*
+*  This program and the accompanying materials are licensed and made available
+*  under the terms and conditions of the BSD License which accompanies this
+*  distribution. The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+*  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __BOOTMONFS_LOADER_H__
+#define __BOOTMONFS_LOADER_H__
+
+/**
+  Check that loading the file is supported.
+
+  Not all information is checked, only the properties that matters to us in
+  our simplified loader.
+
+  BootMonFS file properties is not in a file header but in the file-system
+  metadata, so we need to pass a handle to the file to allow access to the
+  information.
+
+  @param[in] FileHandle  Handle of the file to check.
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the header is invalid.
+  @retval EFI_UNSUPPORTED if the file type/platform is not supported.
+**/
+EFI_STATUS
+BootMonFsCheckFile (
+  IN  CONST EFI_FILE_HANDLE  FileHandle
+  );
+
+/**
+  Load a binary file from BootMonFS.
+
+  @param[in]  FileHandle    Handle of the file to load.
+
+  @param[in]  FileData      Address  of the file data in memory.
+
+  @param[out] EntryPoint    Will be filled with the ELF entry point address.
+
+  @param[out] ImageSize     Will be filled with the file size in memory. This
+                            will effectively be equal to the sum of the load
+                            region sizes.
+
+  This function assumes the file is valid and supported as checked with
+  BootMonFsCheckFile().
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the file is invalid.
+**/
+EFI_STATUS
+BootMonFsLoadFile (
+  IN  CONST EFI_FILE_HANDLE   FileHandle,
+  IN  CONST VOID             *FileData,
+  OUT VOID                  **EntryPoint,
+  OUT LIST_ENTRY             *LoadList
+  );
+
+#endif // __BOOTMONFS_LOADER_H__
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c
new file mode 100644
index 000000000000..6bb0d22de2fd
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.c
@@ -0,0 +1,340 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include "ArmShellCmdRunAxf.h"
+#include "ElfLoader.h"
+#include "elf_common.h"
+#include "elf32.h"
+#include "elf64.h"
+
+
+// Put the functions the #ifdef. We only use the appropriate one for the platform.
+// This prevents 'defined but not used' compiler warning.
+#ifdef MDE_CPU_ARM
+STATIC
+BOOLEAN
+IsArmElf (
+  IN  CONST VOID *Buf
+  )
+{
+  Elf32_Ehdr *Hdr = (Elf32_Ehdr*)Buf;
+
+  if (Hdr->e_ident[EI_CLASS] != ELFCLASS32) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS_32), gRunAxfHiiHandle);
+    return FALSE;
+  }
+
+  if (Hdr->e_machine != EM_ARM) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGMACH_32), gRunAxfHiiHandle);
+    return FALSE;
+  }
+
+  // We don't currently check endianness of ELF data (hdr->e_ident[EI_DATA])
+
+  return TRUE;
+}
+#elif defined(MDE_CPU_AARCH64)
+STATIC
+BOOLEAN
+IsAarch64Elf (
+  IN  CONST VOID *Buf
+  )
+{
+  Elf64_Ehdr *Hdr = (Elf64_Ehdr*)Buf;
+
+  if (Hdr->e_ident[EI_CLASS] != ELFCLASS64) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS_64), gRunAxfHiiHandle);
+    return FALSE;
+  }
+
+  if (Hdr->e_machine != EM_AARCH64) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGMACH_64), gRunAxfHiiHandle);
+    return FALSE;
+  }
+
+  // We don't currently check endianness of ELF data (hdr->e_ident[EI_DATA])
+
+  return TRUE;
+}
+#endif // MDE_CPU_ARM , MDE_CPU_AARCH64
+
+
+/**
+ Support checking 32 and 64bit as the header could be valid, we might just
+ not support loading it.
+**/
+STATIC
+EFI_STATUS
+ElfCheckHeader (
+  IN  CONST VOID *Buf
+  )
+{
+  Elf32_Ehdr *Hdr32 = (Elf32_Ehdr*)Buf;
+
+  if (!IS_ELF (*Hdr32)) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFMAGIC), gRunAxfHiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Hdr32->e_type != ET_EXEC) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOTEXEC), gRunAxfHiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Hdr32->e_ident[EI_CLASS] == ELFCLASS32) {
+    if ((Hdr32->e_phoff == 0) || (Hdr32->e_phentsize == 0) || (Hdr32->e_phnum == 0)) {
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOPROG), gRunAxfHiiHandle);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (Hdr32->e_flags != 0) {
+      DEBUG ((EFI_D_INFO, "Warning: Wrong processor-specific flags, expected 0.\n"));
+    }
+
+    DEBUG ((EFI_D_INFO, "Entry point addr: 0x%lx\n", Hdr32->e_entry));
+    DEBUG ((EFI_D_INFO, "Start of program headers: 0x%lx\n", Hdr32->e_phoff));
+    DEBUG ((EFI_D_INFO, "Size of 1 program header: %d\n", Hdr32->e_phentsize));
+    DEBUG ((EFI_D_INFO, "Number of program headers: %d\n", Hdr32->e_phnum));
+  } else if (Hdr32->e_ident[EI_CLASS] == ELFCLASS64) {
+      Elf64_Ehdr *Hdr64 = (Elf64_Ehdr*)Buf;
+
+    if ((Hdr64->e_phoff == 0) || (Hdr64->e_phentsize == 0) || (Hdr64->e_phnum == 0)) {
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOPROG), gRunAxfHiiHandle);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (Hdr64->e_flags != 0) {
+      DEBUG ((EFI_D_INFO, "Warning: Wrong processor-specific flags, expected 0.\n"));
+    }
+
+    DEBUG ((EFI_D_INFO, "Entry point addr: 0x%lx\n", Hdr64->e_entry));
+    DEBUG ((EFI_D_INFO, "Start of program headers: 0x%lx\n", Hdr64->e_phoff));
+    DEBUG ((EFI_D_INFO, "Size of 1 program header: %d\n", Hdr64->e_phentsize));
+    DEBUG ((EFI_D_INFO, "Number of program headers: %d\n", Hdr64->e_phnum));
+  } else {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS), gRunAxfHiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+ Load an ELF segment into memory.
+
+ This function assumes the ELF file is valid.
+ This function is meant to be called for PT_LOAD type segments only.
+**/
+STATIC
+EFI_STATUS
+ElfLoadSegment (
+  IN  CONST VOID  *ElfImage,
+  IN  CONST VOID  *PHdr,
+  IN  LIST_ENTRY  *LoadList
+  )
+{
+  VOID             *FileSegment;
+  VOID             *MemSegment;
+  UINTN             ExtraZeroes;
+  UINTN             ExtraZeroesCount;
+  RUNAXF_LOAD_LIST *LoadNode;
+
+#ifdef MDE_CPU_ARM
+  Elf32_Phdr  *ProgramHdr;
+  ProgramHdr = (Elf32_Phdr *)PHdr;
+#elif defined(MDE_CPU_AARCH64)
+  Elf64_Phdr  *ProgramHdr;
+  ProgramHdr = (Elf64_Phdr *)PHdr;
+#endif
+
+  ASSERT (ElfImage != NULL);
+  ASSERT (ProgramHdr != NULL);
+
+  FileSegment = (VOID *)((UINTN)ElfImage + ProgramHdr->p_offset);
+  MemSegment = (VOID *)ProgramHdr->p_vaddr;
+
+  // If the segment's memory size p_memsz is larger than the file size p_filesz,
+  // the "extra" bytes are defined to hold the value 0 and to follow the
+  // segment's initialised area.
+  // This is typically the case for the .bss segment.
+  // The file size may not be larger than the memory size.
+  if (ProgramHdr->p_filesz > ProgramHdr->p_memsz) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFBADFORMAT), gRunAxfHiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Load the segment in memory.
+  if (ProgramHdr->p_filesz != 0) {
+    DEBUG ((EFI_D_INFO, "Loading segment from 0x%lx to 0x%lx (size = %ld)\n",
+                 FileSegment, MemSegment, ProgramHdr->p_filesz));
+
+    LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
+    if (LoadNode == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    LoadNode->MemOffset  = (UINTN)MemSegment;
+    LoadNode->FileOffset = (UINTN)FileSegment;
+    LoadNode->Length     = (UINTN)ProgramHdr->p_filesz;
+    InsertTailList (LoadList, &LoadNode->Link);
+  }
+
+  ExtraZeroes = ((UINTN)MemSegment + ProgramHdr->p_filesz);
+  ExtraZeroesCount = ProgramHdr->p_memsz - ProgramHdr->p_filesz;
+  DEBUG ((EFI_D_INFO, "Completing segment with %d zero bytes.\n", ExtraZeroesCount));
+  if (ExtraZeroesCount > 0) {
+    // Extra Node to add the Zeroes.
+    LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
+    if (LoadNode == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    LoadNode->MemOffset  = (UINTN)ExtraZeroes;
+    LoadNode->Zeroes     = TRUE;
+    LoadNode->Length     = ExtraZeroesCount;
+    InsertTailList (LoadList, &LoadNode->Link);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+ Check that the ELF File Header is valid and Machine type supported.
+
+ Not all information is checked in the ELF header, only the stuff that
+ matters to us in our simplified ELF loader.
+
+ @param[in] ElfImage  Address of the ELF file to check.
+
+ @retval EFI_SUCCESS on success.
+ @retval EFI_INVALID_PARAMETER if the header is invalid.
+ @retval EFI_UNSUPPORTED if the file type/platform is not supported.
+**/
+EFI_STATUS
+ElfCheckFile (
+  IN  CONST VOID *ElfImage
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (ElfImage != NULL);
+
+  // Check that the ELF header is valid.
+  Status = ElfCheckHeader (ElfImage);
+  if (EFI_ERROR(Status)) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFBADHEADER), gRunAxfHiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+
+#ifdef MDE_CPU_ARM
+  if (IsArmElf (ElfImage)) {
+    return EFI_SUCCESS;
+  }
+#elif defined(MDE_CPU_AARCH64)
+  if (IsAarch64Elf (ElfImage)) {
+    return EFI_SUCCESS;
+  }
+#endif
+
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_BAD_ARCH), gRunAxfHiiHandle);
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Load a ELF file.
+
+  @param[in] ElfImage       Address of the ELF file in memory.
+
+  @param[out] EntryPoint    Will be filled with the ELF entry point address.
+
+  @param[out] ImageSize     Will be filled with the ELF size in memory. This will
+                            effectively be equal to the sum of the segments sizes.
+
+  This functon assumes the header is valid and supported as checked with
+  ElfCheckFile().
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the ELF file is invalid.
+**/
+EFI_STATUS
+ElfLoadFile (
+  IN  CONST VOID   *ElfImage,
+  OUT VOID        **EntryPoint,
+  OUT LIST_ENTRY   *LoadList
+  )
+{
+  EFI_STATUS    Status;
+  UINT8        *ProgramHdr;
+  UINTN         Index;
+  UINTN         ImageSize;
+
+#ifdef MDE_CPU_ARM
+  Elf32_Ehdr   *ElfHdr;
+  Elf32_Phdr   *ProgramHdrPtr;
+
+  ElfHdr = (Elf32_Ehdr*)ElfImage;
+#elif defined(MDE_CPU_AARCH64)
+  Elf64_Ehdr   *ElfHdr;
+  Elf64_Phdr   *ProgramHdrPtr;
+
+  ElfHdr = (Elf64_Ehdr*)ElfImage;
+#endif
+
+  ASSERT (ElfImage   != NULL);
+  ASSERT (EntryPoint != NULL);
+  ASSERT (LoadList   != NULL);
+
+  ProgramHdr = (UINT8*)ElfImage + ElfHdr->e_phoff;
+  DEBUG ((EFI_D_INFO, "ELF program header entry : 0x%lx\n", ProgramHdr));
+
+  ImageSize = 0;
+
+  // Load every loadable ELF segment into memory.
+  for (Index = 0; Index < ElfHdr->e_phnum; ++Index) {
+
+#ifdef MDE_CPU_ARM
+    ProgramHdrPtr = (Elf32_Phdr*)ProgramHdr;
+#elif defined(MDE_CPU_AARCH64)
+    ProgramHdrPtr = (Elf64_Phdr*)ProgramHdr;
+#endif
+
+    // Only consider PT_LOAD type segments, ignore others.
+    if (ProgramHdrPtr->p_type == PT_LOAD) {
+      Status = ElfLoadSegment (ElfImage, (VOID *)ProgramHdrPtr, LoadList);
+      if (EFI_ERROR (Status)) {
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFFAILSEG), gRunAxfHiiHandle);
+        return EFI_INVALID_PARAMETER;
+      }
+      ImageSize += ProgramHdrPtr->p_memsz;
+    }
+    ProgramHdr += ElfHdr->e_phentsize;
+  }
+
+  if (ImageSize == 0) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOSEG), gRunAxfHiiHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Return the entry point specified in the ELF header.
+  *EntryPoint = (void*)ElfHdr->e_entry;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h
new file mode 100644
index 000000000000..7020a6c4e726
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/ElfLoader.h
@@ -0,0 +1,64 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef ELF_LOADER_H
+#define ELF_LOADER_H
+
+/**
+  Check that the ELF File Header is valid and Machine type supported.
+
+  Not all information is checked in the ELF header, only the stuff that
+  matters to us in our simplified ELF loader.
+
+  @param[in] ElfImage  Address of the ELF file to check.
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the header is invalid.
+  @retval EFI_UNSUPPORTED if the file type/platform is not supported.
+**/
+EFI_STATUS
+ElfCheckFile (
+  IN  CONST VOID *ElfImage
+  );
+
+
+/**
+  Load a ELF file.
+
+  @param[in]  ElfImage      Address of the ELF file in memory.
+
+  @param[out] EntryPoint    Will be filled with the ELF entry point address.
+
+  @param[out] ImageSize     Will be filled with the ELF size in memory. This will
+                            effectively be equal to the sum of the segments sizes.
+
+  This function assumes the header is valid and supported as checked with
+  ElfCheckFile().
+
+  NOTE:
+   - We don't currently take the segment permissions into account (indicated by
+     the program headers). It can be used to allocate pages with the right
+     read/write/exec permissions.
+
+  @retval EFI_SUCCESS on success.
+  @retval EFI_INVALID_PARAMETER if the ELF file is invalid.
+**/
+EFI_STATUS
+ElfLoadFile (
+  IN  CONST VOID   *ElfImage,
+  OUT VOID        **EntryPoint,
+  OUT LIST_ENTRY   *LoadList
+  );
+
+#endif // ELF_LOADER_H
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c b/Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c
new file mode 100644
index 000000000000..9f4fc780307d
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/RunAxf.c
@@ -0,0 +1,395 @@
+/** @file
+*
+*  Shell command for launching AXF files.
+*
+*  Copyright (c) 2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Guid/GlobalVariable.h>
+
+#include <Library/PrintLib.h>
+#include <Library/HandleParsingLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/ArmLib.h>
+
+#include "ArmShellCmdRunAxf.h"
+#include "ElfLoader.h"
+#include "BootMonFsLoader.h"
+
+// Provide arguments to AXF?
+typedef VOID (*ELF_ENTRYPOINT)(UINTN arg0, UINTN arg1,
+                               UINTN arg2, UINTN arg3);
+
+STATIC
+EFI_STATUS
+ShutdownUefiBootServices (
+  VOID
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   MemoryMapSize;
+  EFI_MEMORY_DESCRIPTOR   *MemoryMap;
+  UINTN                   MapKey;
+  UINTN                   DescriptorSize;
+  UINT32                  DescriptorVersion;
+  UINTN                   Pages;
+
+  MemoryMap = NULL;
+  MemoryMapSize = 0;
+  Pages = 0;
+
+  do {
+    Status = gBS->GetMemoryMap (
+                    &MemoryMapSize,
+                    MemoryMap,
+                    &MapKey,
+                    &DescriptorSize,
+                    &DescriptorVersion
+                    );
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+
+      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+      MemoryMap = AllocatePages (Pages);
+
+      //
+      // Get System MemoryMap
+      //
+      Status = gBS->GetMemoryMap (
+                      &MemoryMapSize,
+                      MemoryMap,
+                      &MapKey,
+                      &DescriptorSize,
+                      &DescriptorVersion
+                      );
+    }
+
+    // Don't do anything between the GetMemoryMap() and ExitBootServices()
+    if (!EFI_ERROR(Status)) {
+      Status = gBS->ExitBootServices (gImageHandle, MapKey);
+      if (EFI_ERROR(Status)) {
+        FreePages (MemoryMap, Pages);
+        MemoryMap = NULL;
+        MemoryMapSize = 0;
+      }
+    }
+  } while (EFI_ERROR(Status));
+
+  return Status;
+}
+
+
+STATIC
+EFI_STATUS
+PreparePlatformHardware (
+  VOID
+  )
+{
+  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
+
+  // Clean before Disable else the Stack gets corrupted with old data.
+  ArmCleanDataCache ();
+  ArmDisableDataCache ();
+  // Invalidate all the entries that might have snuck in.
+  ArmInvalidateDataCache ();
+
+  // Disable and invalidate the instruction cache
+  ArmDisableInstructionCache ();
+  ArmInvalidateInstructionCache ();
+
+  // Turn off MMU
+  ArmDisableMmu();
+
+  return EFI_SUCCESS;
+}
+
+// Process arguments to pass to AXF?
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+  {NULL, TypeMax}
+};
+
+
+/**
+  This is the shell command handler function pointer callback type. 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 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 EFI_SUCCESS         The operation was successful.
+  @return other               The operation failed.
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdRunAxfHandler (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL    *This,
+  IN EFI_SYSTEM_TABLE                      *SystemTable,
+  IN EFI_SHELL_PARAMETERS_PROTOCOL         *ShellParameters,
+  IN EFI_SHELL_PROTOCOL                    *Shell
+  )
+{
+  LIST_ENTRY        *ParamPackage;
+  EFI_STATUS         Status;
+  SHELL_STATUS       ShellStatus;
+  SHELL_FILE_HANDLE  FileHandle;
+  ELF_ENTRYPOINT     StartElf;
+  CONST CHAR16      *FileName;
+  EFI_FILE_INFO     *Info;
+  UINTN              FileSize;
+  VOID              *FileData;
+  VOID              *Entrypoint;
+  LIST_ENTRY         LoadList;
+  LIST_ENTRY        *Node;
+  LIST_ENTRY        *NextNode;
+  RUNAXF_LOAD_LIST  *LoadNode;
+  CHAR16            *TmpFileName;
+  CHAR16            *TmpChar16;
+
+
+  ShellStatus = SHELL_SUCCESS;
+  FileHandle = NULL;
+  FileData = NULL;
+  InitializeListHead (&LoadList);
+
+  // Only install if they are not there yet? First time or every time?
+  // These can change if the shell exits and start again.
+  Status = gBS->InstallMultipleProtocolInterfaces (&gImageHandle,
+                &gEfiShellProtocolGuid, Shell,
+                &gEfiShellParametersProtocolGuid, ShellParameters,
+                NULL);
+
+  if (EFI_ERROR (Status)) {
+    return SHELL_DEVICE_ERROR;
+  }
+
+  // Update the protocols for the application library
+  Status = ShellInitialize ();
+  ASSERT_EFI_ERROR (Status);
+  // Add support to load AXF with optipnal args?
+
+  //
+  // Process Command Line arguments
+  //
+  Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
+  if (EFI_ERROR (Status)) {
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_INVALID_ARG), gRunAxfHiiHandle);
+    ShellStatus = SHELL_INVALID_PARAMETER;
+  } else {
+    //
+    // Check for "-?"
+    //
+    if ((ShellCommandLineGetFlag (ParamPackage, L"-?")) ||
+        (ShellCommandLineGetRawValue (ParamPackage, 1) == NULL)) {
+      //
+      // We didn't get a file to load
+      //
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_INVALID_ARG), gRunAxfHiiHandle);
+      ShellStatus = SHELL_INVALID_PARAMETER;
+    } else {
+      // For the moment we assume we only ever get one file to load with no arguments.
+      FileName = ShellCommandLineGetRawValue (ParamPackage, 1);
+      Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
+      if (EFI_ERROR (Status)) {
+        // BootMonFS supports file extensions, but they are stripped by default
+        // when the NOR is programmed.
+        // Remove the file extension and try to open again.
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_FILE_NOT_FOUND),
+                         gRunAxfHiiHandle, FileName);
+        // Go through the filename and remove file extension. Preserve the
+        // original name.
+        TmpFileName = AllocateCopyPool (StrSize (FileName), (VOID *)FileName);
+        if (TmpFileName != NULL) {
+          TmpChar16 = StrStr (TmpFileName, L".");
+          if (TmpChar16 != NULL) {
+            *TmpChar16 = '\0';
+            DEBUG((EFI_D_ERROR, "Trying to open file: %s\n", TmpFileName));
+            Status = ShellOpenFileByName (TmpFileName, &FileHandle,
+                                          EFI_FILE_MODE_READ, 0);
+          }
+          FreePool (TmpFileName);
+        }
+        // Do we now have an open file after trying again?
+        if (EFI_ERROR (Status)) {
+          ShellStatus = SHELL_INVALID_PARAMETER;
+          FileHandle = NULL;
+        }
+      }
+
+      if (FileHandle != NULL) {
+        Info = ShellGetFileInfo (FileHandle);
+        FileSize = (UINTN) Info->FileSize;
+        FreePool (Info);
+
+        //
+        // Allocate buffer to read file. 'Runtime' so we can access it after
+        // ExitBootServices().
+        //
+        FileData = AllocateRuntimeZeroPool (FileSize);
+        if (FileData == NULL) {
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_NO_MEM), gRunAxfHiiHandle);
+          ShellStatus = SHELL_OUT_OF_RESOURCES;
+        } else {
+          //
+          // Read file into Buffer
+          //
+          Status = ShellReadFile (FileHandle, &FileSize, FileData);
+          if (EFI_ERROR (Status)) {
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_READ_FAIL), gRunAxfHiiHandle);
+            SHELL_FREE_NON_NULL (FileData);
+            FileData = NULL;
+            ShellStatus = SHELL_DEVICE_ERROR;
+          }
+        }
+      }
+    }
+
+    //
+    // Free the command line package
+    //
+    ShellCommandLineFreeVarList (ParamPackage);
+  }
+
+  // We have a file in memory. Try to work out if we can use it.
+  // It can either be in ELF format or BootMonFS format.
+  if (FileData != NULL) {
+    // Do some validation on the file before we try to load it. The file can
+    // either be an proper ELF file or one processed by the FlashLoader.
+    // Since the data might need to go to various locations in memory we cannot
+    // load the data directly while UEFI is running. We use the file loaders to
+    // populate a linked list of data and load addresses. This is processed and
+    // data copied to where it needs to go after calling ExitBootServices. At
+    // that stage we've reached the point of no return, so overwriting UEFI code
+    // does not make a difference.
+    Status = ElfCheckFile (FileData);
+    if (!EFI_ERROR (Status)) {
+      // Load program into memory
+      Status = ElfLoadFile ((VOID*)FileData, &Entrypoint, &LoadList);
+    } else {
+      // Try to see if it is a BootMonFs executable
+      Status = BootMonFsCheckFile ((EFI_FILE_HANDLE)FileHandle);
+      if (!EFI_ERROR (Status)) {
+        // Load program into memory
+        Status = BootMonFsLoadFile ((EFI_FILE_HANDLE)FileHandle,
+                                    (VOID*)FileData, &Entrypoint, &LoadList);
+      } else {
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_BAD_FILE),
+                         gRunAxfHiiHandle);
+        SHELL_FREE_NON_NULL (FileData);
+        ShellStatus = SHELL_UNSUPPORTED;
+      }
+    }
+  }
+
+  // Program load list created.
+  // Shutdown UEFI, copy and jump to code.
+  if (!IsListEmpty (&LoadList) && !EFI_ERROR (Status)) {
+    // Exit boot services here. This means we cannot return and cannot assume to
+    // have access to UEFI functions.
+    Status = ShutdownUefiBootServices ();
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_ERROR,"Can not shutdown UEFI boot services. Status=0x%X\n",
+              Status));
+    } else {
+      // Process linked list. Copy data to Memory.
+      Node = GetFirstNode (&LoadList);
+      while (!IsNull (&LoadList, Node)) {
+        LoadNode = (RUNAXF_LOAD_LIST *)Node;
+        // Do we have data to copy or do we need to set Zeroes (.bss)?
+        if (LoadNode->Zeroes) {
+          ZeroMem ((VOID*)LoadNode->MemOffset, LoadNode->Length);
+        } else {
+          CopyMem ((VOID *)LoadNode->MemOffset, (VOID *)LoadNode->FileOffset,
+                   LoadNode->Length);
+        }
+        Node = GetNextNode (&LoadList, Node);
+      }
+
+      //
+      // Switch off interrupts, caches, mmu, etc
+      //
+      Status = PreparePlatformHardware ();
+      ASSERT_EFI_ERROR (Status);
+
+      StartElf = (ELF_ENTRYPOINT)Entrypoint;
+      StartElf (0,0,0,0);
+
+      // We should never get here.. But if we do, spin..
+      ASSERT (FALSE);
+      while (1);
+    }
+  }
+
+  // Free file related information as we are returning to UEFI.
+  Node = GetFirstNode (&LoadList);
+  while (!IsNull (&LoadList, Node)) {
+    NextNode = RemoveEntryList (Node);
+    FreePool (Node);
+    Node = NextNode;
+  }
+  SHELL_FREE_NON_NULL (FileData);
+  if (FileHandle != NULL) {
+    ShellCloseFile (&FileHandle);
+  }
+
+  // Uninstall protocols as we don't know if they will change.
+  // If the shell exits and come in again these mappings may be different
+  // and cause a crash.
+  Status = gBS->UninstallMultipleProtocolInterfaces (gImageHandle,
+                &gEfiShellProtocolGuid, Shell,
+                &gEfiShellParametersProtocolGuid, ShellParameters,
+                NULL);
+
+  if (EFI_ERROR (Status) && ShellStatus == SHELL_SUCCESS) {
+    ShellStatus = SHELL_DEVICE_ERROR;
+  }
+
+  return ShellStatus;
+}
+
+
+/**
+  This is the command help handler function pointer callback type. This
+  function is responsible for displaying help information for the associated
+  command.
+
+  @param[in] This             The instance of the
+                              EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in] Language         The pointer to the language string to use.
+
+  @return string              Pool allocated help string, must be freed by
+                              caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdRunAxfGetHelp (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL    *This,
+  IN CONST CHAR8                           *Language
+  )
+{
+  CHAR16 *HelpText;
+
+  ASSERT (gRunAxfHiiHandle != NULL);
+
+  // This allocates memory. The caller is responsoible to free.
+  HelpText = HiiGetString (gRunAxfHiiHandle, STRING_TOKEN (STR_GET_HELP_RUNAXF),
+                           Language);
+
+  return HelpText;
+}
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h b/Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h
new file mode 100644
index 000000000000..3951444a3085
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/elf32.h
@@ -0,0 +1,258 @@
+/** @file
+Ported ELF include files from FreeBSD
+
+Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+/*-
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.2 2007/12/03 21:30:36 marius Exp $
+ */
+
+#ifndef _SYS_ELF32_H_
+#define _SYS_ELF32_H_ 1
+
+
+/*
+ * ELF definitions common to all 32-bit architectures.
+ */
+
+typedef UINT32  Elf32_Addr;
+typedef UINT16  Elf32_Half;
+typedef UINT32  Elf32_Off;
+typedef INT32   Elf32_Sword;
+typedef UINT32  Elf32_Word;
+typedef UINT64  Elf32_Lword;
+
+typedef Elf32_Word      Elf32_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf32_Word      Elf32_Size;
+typedef Elf32_Sword     Elf32_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+  unsigned char   e_ident[EI_NIDENT]; /* File identification. */
+  Elf32_Half      e_type;             /* File type. */
+  Elf32_Half      e_machine;          /* Machine architecture. */
+  Elf32_Word      e_version;          /* ELF format version. */
+  Elf32_Addr      e_entry;            /* Entry point. */
+  Elf32_Off       e_phoff;            /* Program header file offset. */
+  Elf32_Off       e_shoff;            /* Section header file offset. */
+  Elf32_Word      e_flags;            /* Architecture-specific flags. */
+  Elf32_Half      e_ehsize;           /* Size of ELF header in bytes. */
+  Elf32_Half      e_phentsize;        /* Size of program header entry. */
+  Elf32_Half      e_phnum;            /* Number of program header entries. */
+  Elf32_Half      e_shentsize;        /* Size of section header entry. */
+  Elf32_Half      e_shnum;            /* Number of section header entries. */
+  Elf32_Half      e_shstrndx;         /* Section name strings section. */
+} Elf32_Ehdr;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+  Elf32_Word      sh_name;        /* Section name (index into the
+                                     section header string table). */
+  Elf32_Word      sh_type;        /* Section type. */
+  Elf32_Word      sh_flags;       /* Section flags. */
+  Elf32_Addr      sh_addr;        /* Address in memory image. */
+  Elf32_Off       sh_offset;      /* Offset in file. */
+  Elf32_Word      sh_size;        /* Size in bytes. */
+  Elf32_Word      sh_link;        /* Index of a related section. */
+  Elf32_Word      sh_info;        /* Depends on section type. */
+  Elf32_Word      sh_addralign;   /* Alignment in bytes. */
+  Elf32_Word      sh_entsize;     /* Size of each entry in section. */
+} Elf32_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+  Elf32_Word      p_type;         /* Entry type. */
+  Elf32_Off       p_offset;       /* File offset of contents. */
+  Elf32_Addr      p_vaddr;        /* Virtual address in memory image. */
+  Elf32_Addr      p_paddr;        /* Physical address (not used). */
+  Elf32_Word      p_filesz;       /* Size of contents in file. */
+  Elf32_Word      p_memsz;        /* Size of contents in memory. */
+  Elf32_Word      p_flags;        /* Access permission flags. */
+  Elf32_Word      p_align;        /* Alignment in memory and file. */
+} Elf32_Phdr;
+
+/*
+ * Dynamic structure.  The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+  Elf32_Sword     d_tag;          /* Entry type. */
+  union {
+    Elf32_Word      d_val;  /* Integer value. */
+    Elf32_Addr      d_ptr;  /* Address value. */
+  } d_un;
+} Elf32_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+  Elf32_Addr      r_offset;       /* Location to be relocated. */
+  Elf32_Word      r_info;         /* Relocation type and symbol index. */
+} Elf32_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+  Elf32_Addr      r_offset;       /* Location to be relocated. */
+  Elf32_Word      r_info;         /* Relocation type and symbol index. */
+  Elf32_Sword     r_addend;       /* Addend. */
+} Elf32_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF32_R_SYM(info)       ((info) >> 8)
+#define ELF32_R_TYPE(info)      ((unsigned char)(info))
+
+/* Macro for constructing r_info from field values. */
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
+
+/*
+ *      Note entry header
+ */
+typedef Elf_Note Elf32_Nhdr;
+
+/*
+ *      Move entry
+ */
+typedef struct {
+  Elf32_Lword     m_value;        /* symbol value */
+  Elf32_Word      m_info;         /* size + index */
+  Elf32_Word      m_poffset;      /* symbol offset */
+  Elf32_Half      m_repeat;       /* repeat count */
+  Elf32_Half      m_stride;       /* stride info */
+} Elf32_Move;
+
+/*
+ *      The macros compose and decompose values for Move.r_info
+ *
+ *      sym = ELF32_M_SYM(M.m_info)
+ *      size = ELF32_M_SIZE(M.m_info)
+ *      M.m_info = ELF32_M_INFO(sym, size)
+ */
+#define ELF32_M_SYM(info)       ((info)>>8)
+#define ELF32_M_SIZE(info)      ((unsigned char)(info))
+#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ *      Hardware/Software capabilities entry
+ */
+typedef struct {
+  Elf32_Word      c_tag;          /* how to interpret value */
+  union {
+    Elf32_Word      c_val;
+    Elf32_Addr      c_ptr;
+  } c_un;
+} Elf32_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+  Elf32_Word      st_name;        /* String table index of name. */
+  Elf32_Addr      st_value;       /* Symbol value. */
+  Elf32_Word      st_size;        /* Size of associated object. */
+  unsigned char   st_info;        /* Type and binding information. */
+  unsigned char   st_other;       /* Reserved (not used). */
+  Elf32_Half      st_shndx;       /* Section index of symbol. */
+} Elf32_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF32_ST_BIND(info)             ((info) >> 4)
+#define ELF32_ST_TYPE(info)             ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF32_ST_VISIBILITY(oth)        ((oth) & 0x3)
+
+/* Structures used by Sun & GNU symbol versioning. */
+typedef struct
+{
+  Elf32_Half      vd_version;
+  Elf32_Half      vd_flags;
+  Elf32_Half      vd_ndx;
+  Elf32_Half      vd_cnt;
+  Elf32_Word      vd_hash;
+  Elf32_Word      vd_aux;
+  Elf32_Word      vd_next;
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf32_Word      vda_name;
+  Elf32_Word      vda_next;
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf32_Half      vn_version;
+  Elf32_Half      vn_cnt;
+  Elf32_Word      vn_file;
+  Elf32_Word      vn_aux;
+  Elf32_Word      vn_next;
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf32_Word      vna_hash;
+  Elf32_Half      vna_flags;
+  Elf32_Half      vna_other;
+  Elf32_Word      vna_name;
+  Elf32_Word      vna_next;
+} Elf32_Vernaux;
+
+typedef Elf32_Half Elf32_Versym;
+
+typedef struct {
+  Elf32_Half      si_boundto;     /* direct bindings - symbol bound to */
+  Elf32_Half      si_flags;       /* per symbol flags */
+} Elf32_Syminfo;
+
+#endif /* !_SYS_ELF32_H_ */
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h b/Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h
new file mode 100644
index 000000000000..1cfe0c9539aa
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/elf64.h
@@ -0,0 +1,260 @@
+/** @file
+Ported ELF include files from FreeBSD
+
+Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/*-
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.2 2007/12/03 21:30:36 marius Exp $
+ */
+
+#ifndef _SYS_ELF64_H_
+#define _SYS_ELF64_H_ 1
+
+
+/*
+ * ELF definitions common to all 64-bit architectures.
+ */
+
+typedef UINT64  Elf64_Addr;
+typedef UINT16  Elf64_Half;
+typedef UINT64  Elf64_Off;
+typedef INT32   Elf64_Sword;
+typedef INT64   Elf64_Sxword;
+typedef UINT32  Elf64_Word;
+typedef UINT64  Elf64_Lword;
+typedef UINT64  Elf64_Xword;
+
+/*
+ * Types of dynamic symbol hash table bucket and chain elements.
+ *
+ * This is inconsistent among 64 bit architectures, so a machine dependent
+ * typedef is required.
+ */
+
+typedef Elf64_Word      Elf64_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf64_Xword     Elf64_Size;
+typedef Elf64_Sxword    Elf64_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+  unsigned char   e_ident[EI_NIDENT]; /* File identification. */
+  Elf64_Half      e_type;             /* File type. */
+  Elf64_Half      e_machine;          /* Machine architecture. */
+  Elf64_Word      e_version;          /* ELF format version. */
+  Elf64_Addr      e_entry;            /* Entry point. */
+  Elf64_Off       e_phoff;            /* Program header file offset. */
+  Elf64_Off       e_shoff;            /* Section header file offset. */
+  Elf64_Word      e_flags;            /* Architecture-specific flags. */
+  Elf64_Half      e_ehsize;           /* Size of ELF header in bytes. */
+  Elf64_Half      e_phentsize;        /* Size of program header entry. */
+  Elf64_Half      e_phnum;            /* Number of program header entries. */
+  Elf64_Half      e_shentsize;        /* Size of section header entry. */
+  Elf64_Half      e_shnum;            /* Number of section header entries. */
+  Elf64_Half      e_shstrndx;         /* Section name strings section. */
+} Elf64_Ehdr;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+  Elf64_Word      sh_name;        /* Section name (index into the
+                                     section header string table). */
+  Elf64_Word      sh_type;        /* Section type. */
+  Elf64_Xword     sh_flags;       /* Section flags. */
+  Elf64_Addr      sh_addr;        /* Address in memory image. */
+  Elf64_Off       sh_offset;      /* Offset in file. */
+  Elf64_Xword     sh_size;        /* Size in bytes. */
+  Elf64_Word      sh_link;        /* Index of a related section. */
+  Elf64_Word      sh_info;        /* Depends on section type. */
+  Elf64_Xword     sh_addralign;   /* Alignment in bytes. */
+  Elf64_Xword     sh_entsize;     /* Size of each entry in section. */
+} Elf64_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+  Elf64_Word      p_type;         /* Entry type. */
+  Elf64_Word      p_flags;        /* Access permission flags. */
+  Elf64_Off       p_offset;       /* File offset of contents. */
+  Elf64_Addr      p_vaddr;        /* Virtual address in memory image. */
+  Elf64_Addr      p_paddr;        /* Physical address (not used). */
+  Elf64_Xword     p_filesz;       /* Size of contents in file. */
+  Elf64_Xword     p_memsz;        /* Size of contents in memory. */
+  Elf64_Xword     p_align;        /* Alignment in memory and file. */
+} Elf64_Phdr;
+
+/*
+ * Dynamic structure.  The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+  Elf64_Sxword    d_tag;          /* Entry type. */
+  union {
+    Elf64_Xword     d_val;  /* Integer value. */
+    Elf64_Addr      d_ptr;  /* Address value. */
+  } d_un;
+} Elf64_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+  Elf64_Addr      r_offset;       /* Location to be relocated. */
+  Elf64_Xword     r_info;         /* Relocation type and symbol index. */
+} Elf64_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+  Elf64_Addr      r_offset;       /* Location to be relocated. */
+  Elf64_Xword     r_info;         /* Relocation type and symbol index. */
+  Elf64_Sxword    r_addend;       /* Addend. */
+} Elf64_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF64_R_SYM(info)       ((info) >> 32)
+#define ELF64_R_TYPE(info)      ((info) & 0xffffffffL)
+
+/* Macro for constructing r_info from field values. */
+#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
+
+#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
+#define ELF64_R_TYPE_ID(info)   (((Elf64_Xword)(info)<<56)>>56)
+#define ELF64_R_TYPE_INFO(data, type)   \
+                (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
+
+/*
+ *      Note entry header
+ */
+typedef Elf_Note Elf64_Nhdr;
+
+/*
+ *      Move entry
+ */
+typedef struct {
+  Elf64_Lword     m_value;        /* symbol value */
+  Elf64_Xword     m_info;         /* size + index */
+  Elf64_Xword     m_poffset;      /* symbol offset */
+  Elf64_Half      m_repeat;       /* repeat count */
+  Elf64_Half      m_stride;       /* stride info */
+} Elf64_Move;
+
+#define ELF64_M_SYM(info)       ((info)>>8)
+#define ELF64_M_SIZE(info)      ((unsigned char)(info))
+#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ *      Hardware/Software capabilities entry
+ */
+typedef struct {
+  Elf64_Xword     c_tag;          /* how to interpret value */
+  union {
+    Elf64_Xword     c_val;
+    Elf64_Addr      c_ptr;
+  } c_un;
+} Elf64_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+  Elf64_Word      st_name;        /* String table index of name. */
+  unsigned char   st_info;        /* Type and binding information. */
+  unsigned char   st_other;       /* Reserved (not used). */
+  Elf64_Half      st_shndx;       /* Section index of symbol. */
+  Elf64_Addr      st_value;       /* Symbol value. */
+  Elf64_Xword     st_size;        /* Size of associated object. */
+} Elf64_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF64_ST_BIND(info)             ((info) >> 4)
+#define ELF64_ST_TYPE(info)             ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF64_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF64_ST_VISIBILITY(oth)        ((oth) & 0x3)
+
+/* Structures used by Sun & GNU-style symbol versioning. */
+typedef struct {
+  Elf64_Half      vd_version;
+  Elf64_Half      vd_flags;
+  Elf64_Half      vd_ndx;
+  Elf64_Half      vd_cnt;
+  Elf64_Word      vd_hash;
+  Elf64_Word      vd_aux;
+  Elf64_Word      vd_next;
+} Elf64_Verdef;
+
+typedef struct {
+  Elf64_Word      vda_name;
+  Elf64_Word      vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+  Elf64_Half      vn_version;
+  Elf64_Half      vn_cnt;
+  Elf64_Word      vn_file;
+  Elf64_Word      vn_aux;
+  Elf64_Word      vn_next;
+} Elf64_Verneed;
+
+typedef struct {
+  Elf64_Word      vna_hash;
+  Elf64_Half      vna_flags;
+  Elf64_Half      vna_other;
+  Elf64_Word      vna_name;
+  Elf64_Word      vna_next;
+} Elf64_Vernaux;
+
+typedef Elf64_Half Elf64_Versym;
+
+typedef struct {
+  Elf64_Half      si_boundto;     /* direct bindings - symbol bound to */
+  Elf64_Half      si_flags;       /* per symbol flags */
+} Elf64_Syminfo;
+
+#endif /* !_SYS_ELF64_H_ */
diff --git a/Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h b/Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h
new file mode 100644
index 000000000000..ed3cedc1b076
--- /dev/null
+++ b/Platform/ARM/Library/ArmShellCmdRunAxf/elf_common.h
@@ -0,0 +1,1059 @@
+/** @file
+Ported ELF include files from FreeBSD
+
+Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+/*-
+ * Copyright (c) 1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.2 2007/12/03 21:30:36 marius Exp $
+ */
+
+#ifndef _SYS_ELF_COMMON_H_
+#define _SYS_ELF_COMMON_H_ 1
+
+/*
+ * ELF definitions that are independent of architecture or word size.
+ */
+
+/*
+ * Note header.  The ".note" section contains an array of notes.  Each
+ * begins with this header, aligned to a word boundary.  Immediately
+ * following the note header is n_namesz bytes of name, padded to the
+ * next word boundary.  Then comes n_descsz bytes of descriptor, again
+ * padded to a word boundary.  The values of n_namesz and n_descsz do
+ * not include the padding.
+ */
+
+typedef struct {
+        UINT32  n_namesz;       /* Length of name. */
+        UINT32  n_descsz;       /* Length of descriptor. */
+        UINT32  n_type;         /* Type of this note. */
+} Elf_Note;
+
+/* Indexes into the e_ident array.  Keep synced with
+   http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EI_MAG0         0       /* Magic number, byte 0. */
+#define EI_MAG1         1       /* Magic number, byte 1. */
+#define EI_MAG2         2       /* Magic number, byte 2. */
+#define EI_MAG3         3       /* Magic number, byte 3. */
+#define EI_CLASS        4       /* Class of machine. */
+#define EI_DATA         5       /* Data format. */
+#define EI_VERSION      6       /* ELF format version. */
+#define EI_OSABI        7       /* Operating system / ABI identification */
+#define EI_ABIVERSION   8       /* ABI version */
+#define OLD_EI_BRAND    8       /* Start of architecture identification. */
+#define EI_PAD          9       /* Start of padding (per SVR4 ABI). */
+#define EI_NIDENT       16      /* Size of e_ident array. */
+
+/* Values for the magic number bytes. */
+#define ELFMAG0         0x7f
+#define ELFMAG1         'E'
+#define ELFMAG2         'L'
+#define ELFMAG3         'F'
+#define ELFMAG          "\177ELF"       /* magic string */
+#define SELFMAG         4               /* magic string size */
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define EV_NONE         0
+#define EV_CURRENT      1
+
+/* Values for e_ident[EI_CLASS]. */
+#define ELFCLASSNONE    0       /* Unknown class. */
+#define ELFCLASS32      1       /* 32-bit architecture. */
+#define ELFCLASS64      2       /* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define ELFDATANONE     0       /* Unknown data format. */
+#define ELFDATA2LSB     1       /* 2's complement little-endian. */
+#define ELFDATA2MSB     2       /* 2's complement big-endian. */
+
+/* Values for e_ident[EI_OSABI]. */
+#define ELFOSABI_NONE           0       /* UNIX System V ABI */
+#define ELFOSABI_HPUX           1       /* HP-UX operating system */
+#define ELFOSABI_NETBSD         2       /* NetBSD */
+#define ELFOSABI_LINUX          3       /* GNU/Linux */
+#define ELFOSABI_HURD           4       /* GNU/Hurd */
+#define ELFOSABI_86OPEN         5       /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS        6       /* Solaris */
+#define ELFOSABI_AIX            7       /* AIX */
+#define ELFOSABI_IRIX           8       /* IRIX */
+#define ELFOSABI_FREEBSD        9       /* FreeBSD */
+#define ELFOSABI_TRU64          10      /* TRU64 UNIX */
+#define ELFOSABI_MODESTO        11      /* Novell Modesto */
+#define ELFOSABI_OPENBSD        12      /* OpenBSD */
+#define ELFOSABI_OPENVMS        13      /* Open VMS */
+#define ELFOSABI_NSK            14      /* HP Non-Stop Kernel */
+#define ELFOSABI_ARM            97      /* ARM */
+#define ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
+
+#define ELFOSABI_SYSV           ELFOSABI_NONE   /* symbol used in old spec */
+#define ELFOSABI_MONTEREY       ELFOSABI_AIX    /* Monterey */
+
+/* e_ident */
+#define IS_ELF(ehdr)    ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+                         (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+                         (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+                         (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define ET_NONE         0       /* Unknown type. */
+#define ET_REL          1       /* Relocatable. */
+#define ET_EXEC         2       /* Executable. */
+#define ET_DYN          3       /* Shared object. */
+#define ET_CORE         4       /* Core file. */
+#define ET_LOOS         0xfe00  /* First operating system specific. */
+#define ET_HIOS         0xfeff  /* Last operating system-specific. */
+#define ET_LOPROC       0xff00  /* First processor-specific. */
+#define ET_HIPROC       0xffff  /* Last processor-specific. */
+
+/* Values for e_machine. */
+#define EM_NONE         0       /* Unknown machine. */
+#define EM_M32          1       /* AT&T WE32100. */
+#define EM_SPARC        2       /* Sun SPARC. */
+#define EM_386          3       /* Intel i386. */
+#define EM_68K          4       /* Motorola 68000. */
+#define EM_88K          5       /* Motorola 88000. */
+#define EM_860          7       /* Intel i860. */
+#define EM_MIPS         8       /* MIPS R3000 Big-Endian only. */
+#define EM_S370         9       /* IBM System/370. */
+#define EM_MIPS_RS3_LE  10      /* MIPS R3000 Little-Endian. */
+#define EM_PARISC       15      /* HP PA-RISC. */
+#define EM_VPP500       17      /* Fujitsu VPP500. */
+#define EM_SPARC32PLUS  18      /* SPARC v8plus. */
+#define EM_960          19      /* Intel 80960. */
+#define EM_PPC          20      /* PowerPC 32-bit. */
+#define EM_PPC64        21      /* PowerPC 64-bit. */
+#define EM_S390         22      /* IBM System/390. */
+#define EM_V800         36      /* NEC V800. */
+#define EM_FR20         37      /* Fujitsu FR20. */
+#define EM_RH32         38      /* TRW RH-32. */
+#define EM_RCE          39      /* Motorola RCE. */
+#define EM_ARM          40      /* ARM. */
+#define EM_SH           42      /* Hitachi SH. */
+#define EM_SPARCV9      43      /* SPARC v9 64-bit. */
+#define EM_TRICORE      44      /* Siemens TriCore embedded processor. */
+#define EM_ARC          45      /* Argonaut RISC Core. */
+#define EM_H8_300       46      /* Hitachi H8/300. */
+#define EM_H8_300H      47      /* Hitachi H8/300H. */
+#define EM_H8S          48      /* Hitachi H8S. */
+#define EM_H8_500       49      /* Hitachi H8/500. */
+#define EM_IA_64        50      /* Intel IA-64 Processor. */
+#define EM_MIPS_X       51      /* Stanford MIPS-X. */
+#define EM_COLDFIRE     52      /* Motorola ColdFire. */
+#define EM_68HC12       53      /* Motorola M68HC12. */
+#define EM_MMA          54      /* Fujitsu MMA. */
+#define EM_PCP          55      /* Siemens PCP. */
+#define EM_NCPU         56      /* Sony nCPU. */
+#define EM_NDR1         57      /* Denso NDR1 microprocessor. */
+#define EM_STARCORE     58      /* Motorola Star*Core processor. */
+#define EM_ME16         59      /* Toyota ME16 processor. */
+#define EM_ST100        60      /* STMicroelectronics ST100 processor. */
+#define EM_TINYJ        61      /* Advanced Logic Corp. TinyJ processor. */
+#define EM_X86_64       62      /* Advanced Micro Devices x86-64 */
+#define EM_AMD64        EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
+#define EM_AARCH64      183     /* ARM 64bit Architecture */
+
+/* Non-standard or deprecated. */
+#define EM_486          6       /* Intel i486. */
+#define EM_MIPS_RS4_BE  10      /* MIPS R4000 Big-Endian */
+#define EM_ALPHA_STD    41      /* Digital Alpha (standard value). */
+#define EM_ALPHA        0x9026  /* Alpha (written in the absence of an ABI) */
+
+/* Special section indexes. */
+#define SHN_UNDEF            0          /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE   0xff00          /* First of reserved range. */
+#define SHN_LOPROC      0xff00          /* First processor-specific. */
+#define SHN_HIPROC      0xff1f          /* Last processor-specific. */
+#define SHN_LOOS        0xff20          /* First operating system-specific. */
+#define SHN_HIOS        0xff3f          /* Last operating system-specific. */
+#define SHN_ABS         0xfff1          /* Absolute values. */
+#define SHN_COMMON      0xfff2          /* Common data. */
+#define SHN_XINDEX      0xffff          /* Escape -- index stored elsewhere. */
+#define SHN_HIRESERVE   0xffff          /* Last of reserved range. */
+
+/* sh_type */
+#define SHT_NULL                0       /* inactive */
+#define SHT_PROGBITS            1       /* program defined information */
+#define SHT_SYMTAB              2       /* symbol table section */
+#define SHT_STRTAB              3       /* string table section */
+#define SHT_RELA                4       /* relocation section with addends */
+#define SHT_HASH                5       /* symbol hash table section */
+#define SHT_DYNAMIC             6       /* dynamic section */
+#define SHT_NOTE                7       /* note section */
+#define SHT_NOBITS              8       /* no space section */
+#define SHT_REL                 9       /* relocation section - no addends */
+#define SHT_SHLIB               10      /* reserved - purpose unknown */
+#define SHT_DYNSYM              11      /* dynamic symbol table section */
+#define SHT_INIT_ARRAY          14      /* Initialization function pointers. */
+#define SHT_FINI_ARRAY          15      /* Termination function pointers. */
+#define SHT_PREINIT_ARRAY       16      /* Pre-initialization function ptrs. */
+#define SHT_GROUP               17      /* Section group. */
+#define SHT_SYMTAB_SHNDX        18      /* Section indexes (see SHN_XINDEX). */
+#define SHT_LOOS                0x60000000      /* First of OS specific semantics */
+#define SHT_LOSUNW              0x6ffffff4
+#define SHT_SUNW_dof            0x6ffffff4
+#define SHT_SUNW_cap            0x6ffffff5
+#define SHT_SUNW_SIGNATURE      0x6ffffff6
+#define SHT_SUNW_ANNOTATE       0x6ffffff7
+#define SHT_SUNW_DEBUGSTR       0x6ffffff8
+#define SHT_SUNW_DEBUG          0x6ffffff9
+#define SHT_SUNW_move           0x6ffffffa
+#define SHT_SUNW_COMDAT         0x6ffffffb
+#define SHT_SUNW_syminfo        0x6ffffffc
+#define SHT_SUNW_verdef         0x6ffffffd
+#define SHT_GNU_verdef          0x6ffffffd      /* Symbol versions provided */
+#define SHT_SUNW_verneed        0x6ffffffe
+#define SHT_GNU_verneed         0x6ffffffe      /* Symbol versions required */
+#define SHT_SUNW_versym         0x6fffffff
+#define SHT_GNU_versym          0x6fffffff      /* Symbol version table */
+#define SHT_HISUNW              0x6fffffff
+#define SHT_HIOS                0x6fffffff      /* Last of OS specific semantics */
+#define SHT_LOPROC              0x70000000      /* reserved range for processor */
+#define SHT_AMD64_UNWIND        0x70000001      /* unwind information */
+#define SHT_HIPROC              0x7fffffff      /* specific section header types */
+#define SHT_LOUSER              0x80000000      /* reserved range for application */
+#define SHT_HIUSER              0xffffffff      /* specific indexes */
+
+/* Flags for sh_flags. */
+#define SHF_WRITE               0x1     /* Section contains writable data. */
+#define SHF_ALLOC               0x2     /* Section occupies memory. */
+#define SHF_EXECINSTR           0x4     /* Section contains instructions. */
+#define SHF_MERGE               0x10    /* Section may be merged. */
+#define SHF_STRINGS             0x20    /* Section contains strings. */
+#define SHF_INFO_LINK           0x40    /* sh_info holds section index. */
+#define SHF_LINK_ORDER          0x80    /* Special ordering requirements. */
+#define SHF_OS_NONCONFORMING    0x100   /* OS-specific processing required. */
+#define SHF_GROUP               0x200   /* Member of section group. */
+#define SHF_TLS                 0x400   /* Section contains TLS data. */
+#define SHF_MASKOS      0x0ff00000      /* OS-specific semantics. */
+#define SHF_MASKPROC    0xf0000000      /* Processor-specific semantics. */
+
+/* Values for p_type. */
+#define PT_NULL         0       /* Unused entry. */
+#define PT_LOAD         1       /* Loadable segment. */
+#define PT_DYNAMIC      2       /* Dynamic linking information segment. */
+#define PT_INTERP       3       /* Pathname of interpreter. */
+#define PT_NOTE         4       /* Auxiliary information. */
+#define PT_SHLIB        5       /* Reserved (not used). */
+#define PT_PHDR         6       /* Location of program header itself. */
+#define PT_TLS          7       /* Thread local storage segment */
+#define PT_LOOS         0x60000000      /* First OS-specific. */
+#define PT_SUNW_UNWIND  0x6464e550      /* amd64 UNWIND program header */
+#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_LOSUNW       0x6ffffffa
+#define PT_SUNWBSS      0x6ffffffa      /* Sun Specific segment */
+#define PT_SUNWSTACK    0x6ffffffb      /* describes the stack segment */
+#define PT_SUNWDTRACE   0x6ffffffc      /* private */
+#define PT_SUNWCAP      0x6ffffffd      /* hard/soft capabilities segment */
+#define PT_HISUNW       0x6fffffff
+#define PT_HIOS         0x6fffffff      /* Last OS-specific. */
+#define PT_LOPROC       0x70000000      /* First processor-specific type. */
+#define PT_HIPROC       0x7fffffff      /* Last processor-specific type. */
+
+/* Values for p_flags. */
+#define PF_X            0x1             /* Executable. */
+#define PF_W            0x2             /* Writable. */
+#define PF_R            0x4             /* Readable. */
+#define PF_MASKOS       0x0ff00000      /* Operating system-specific. */
+#define PF_MASKPROC     0xf0000000      /* Processor-specific. */
+
+/* Extended program header index. */
+#define PN_XNUM         0xffff
+
+/* Values for d_tag. */
+#define DT_NULL         0       /* Terminating entry. */
+#define DT_NEEDED       1       /* String table offset of a needed shared
+                                   library. */
+#define DT_PLTRELSZ     2       /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT       3       /* Processor-dependent address. */
+#define DT_HASH         4       /* Address of symbol hash table. */
+#define DT_STRTAB       5       /* Address of string table. */
+#define DT_SYMTAB       6       /* Address of symbol table. */
+#define DT_RELA         7       /* Address of ElfNN_Rela relocations. */
+#define DT_RELASZ       8       /* Total size of ElfNN_Rela relocations. */
+#define DT_RELAENT      9       /* Size of each ElfNN_Rela relocation entry. */
+#define DT_STRSZ        10      /* Size of string table. */
+#define DT_SYMENT       11      /* Size of each symbol table entry. */
+#define DT_INIT         12      /* Address of initialization function. */
+#define DT_FINI         13      /* Address of finalization function. */
+#define DT_SONAME       14      /* String table offset of shared object
+                                   name. */
+#define DT_RPATH        15      /* String table offset of library path. [sup] */
+#define DT_SYMBOLIC     16      /* Indicates "symbolic" linking. [sup] */
+#define DT_REL          17      /* Address of ElfNN_Rel relocations. */
+#define DT_RELSZ        18      /* Total size of ElfNN_Rel relocations. */
+#define DT_RELENT       19      /* Size of each ElfNN_Rel relocation. */
+#define DT_PLTREL       20      /* Type of relocation used for PLT. */
+#define DT_DEBUG        21      /* Reserved (not used). */
+#define DT_TEXTREL      22      /* Indicates there may be relocations in
+                                   non-writable segments. [sup] */
+#define DT_JMPREL       23      /* Address of PLT relocations. */
+#define DT_BIND_NOW     24      /* [sup] */
+#define DT_INIT_ARRAY   25      /* Address of the array of pointers to
+                                   initialization functions */
+#define DT_FINI_ARRAY   26      /* Address of the array of pointers to
+                                   termination functions */
+#define DT_INIT_ARRAYSZ 27      /* Size in bytes of the array of
+                                   initialization functions. */
+#define DT_FINI_ARRAYSZ 28      /* Size in bytes of the array of
+                                   terminationfunctions. */
+#define DT_RUNPATH      29      /* String table offset of a null-terminated
+                                   library search path string. */
+#define DT_FLAGS        30      /* Object specific flag values. */
+#define DT_ENCODING     32      /* Values greater than or equal to DT_ENCODING
+                                   and less than DT_LOOS follow the rules for
+                                   the interpretation of the d_un union
+                                   as follows: even == 'd_ptr', even == 'd_val'
+                                   or none */
+#define DT_PREINIT_ARRAY   32   /* Address of the array of pointers to
+                                   pre-initialization functions. */
+#define DT_PREINIT_ARRAYSZ 33   /* Size in bytes of the array of
+                                   pre-initialization functions. */
+#define DT_MAXPOSTAGS      34   /* number of positive tags */
+#define DT_LOOS            0x6000000d      /* First OS-specific */
+#define DT_SUNW_AUXILIARY  0x6000000d      /* symbol auxiliary name */
+#define DT_SUNW_RTLDINF    0x6000000e      /* ld.so.1 info (private) */
+#define DT_SUNW_FILTER     0x6000000f      /* symbol filter name */
+#define DT_SUNW_CAP        0x60000010      /* hardware/software */
+#define DT_HIOS            0x6ffff000      /* Last OS-specific */
+
+/*
+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ * Dyn.d_un.d_val field of the Elf*_Dyn structure.
+ */
+#define DT_VALRNGLO     0x6ffffd00
+#define DT_CHECKSUM     0x6ffffdf8      /* elf checksum */
+#define DT_PLTPADSZ     0x6ffffdf9      /* pltpadding size */
+#define DT_MOVEENT      0x6ffffdfa      /* move table entry size */
+#define DT_MOVESZ       0x6ffffdfb      /* move table size */
+#define DT_FEATURE_1    0x6ffffdfc      /* feature holder */
+#define DT_POSFLAG_1    0x6ffffdfd      /* flags for DT_* entries, effecting */
+                                        /*      the following DT_* entry. */
+                                        /*      See DF_P1_* definitions */
+#define DT_SYMINSZ      0x6ffffdfe      /* syminfo table size (in bytes) */
+#define DT_SYMINENT     0x6ffffdff      /* syminfo entry size (in bytes) */
+#define DT_VALRNGHI     0x6ffffdff
+
+/*
+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+ *
+ * If any adjustment is made to the ELF object after it has been
+ * built, these entries will need to be adjusted.
+ */
+#define DT_ADDRRNGLO    0x6ffffe00
+#define DT_CONFIG       0x6ffffefa      /* configuration information */
+#define DT_DEPAUDIT     0x6ffffefb      /* dependency auditing */
+#define DT_AUDIT        0x6ffffefc      /* object auditing */
+#define DT_PLTPAD       0x6ffffefd      /* pltpadding (sparcv9) */
+#define DT_MOVETAB      0x6ffffefe      /* move table */
+#define DT_SYMINFO      0x6ffffeff      /* syminfo table */
+#define DT_ADDRRNGHI    0x6ffffeff
+
+#define DT_VERSYM       0x6ffffff0      /* Address of versym section. */
+#define DT_RELACOUNT    0x6ffffff9      /* number of RELATIVE relocations */
+#define DT_RELCOUNT     0x6ffffffa      /* number of RELATIVE relocations */
+#define DT_FLAGS_1      0x6ffffffb      /* state flags - see DF_1_* defs */
+#define DT_VERDEF       0x6ffffffc      /* Address of verdef section. */
+#define DT_VERDEFNUM    0x6ffffffd      /* Number of elems in verdef section */
+#define DT_VERNEED      0x6ffffffe      /* Address of verneed section. */
+#define DT_VERNEEDNUM   0x6fffffff      /* Number of elems in verneed section */
+
+#define DT_LOPROC       0x70000000      /* First processor-specific type. */
+#define DT_DEPRECATED_SPARC_REGISTER    0x7000001
+#define DT_AUXILIARY    0x7ffffffd      /* shared library auxiliary name */
+#define DT_USED         0x7ffffffe      /* ignored - same as needed */
+#define DT_FILTER       0x7fffffff      /* shared library filter name */
+#define DT_HIPROC       0x7fffffff      /* Last processor-specific type. */
+
+/* Values for DT_FLAGS */
+#define DF_ORIGIN       0x0001  /* Indicates that the object being loaded may
+                                   make reference to the $ORIGIN substitution
+                                   string */
+#define DF_SYMBOLIC     0x0002  /* Indicates "symbolic" linking. */
+#define DF_TEXTREL      0x0004  /* Indicates there may be relocations in
+                                   non-writable segments. */
+#define DF_BIND_NOW     0x0008  /* Indicates that the dynamic linker should
+                                   process all relocations for the object
+                                   containing this entry before transferring
+                                   control to the program. */
+#define DF_STATIC_TLS   0x0010  /* Indicates that the shared object or
+                                   executable contains code using a static
+                                   thread-local storage scheme. */
+
+/* Values for n_type.  Used in core files. */
+#define NT_PRSTATUS     1       /* Process status. */
+#define NT_FPREGSET     2       /* Floating point registers. */
+#define NT_PRPSINFO     3       /* Process state info. */
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+#define STB_LOCAL       0       /* Local symbol */
+#define STB_GLOBAL      1       /* Global symbol */
+#define STB_WEAK        2       /* like global - lower precedence */
+#define STB_LOOS        10      /* Reserved range for operating system */
+#define STB_HIOS        12      /*   specific semantics. */
+#define STB_LOPROC      13      /* reserved range for processor */
+#define STB_HIPROC      15      /*   specific semantics. */
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+#define STT_NOTYPE      0       /* Unspecified type. */
+#define STT_OBJECT      1       /* Data object. */
+#define STT_FUNC        2       /* Function. */
+#define STT_SECTION     3       /* Section. */
+#define STT_FILE        4       /* Source file. */
+#define STT_COMMON      5       /* Uninitialized common block. */
+#define STT_TLS         6       /* TLS object. */
+#define STT_NUM         7
+#define STT_LOOS        10      /* Reserved range for operating system */
+#define STT_HIOS        12      /*   specific semantics. */
+#define STT_LOPROC      13      /* reserved range for processor */
+#define STT_HIPROC      15      /*   specific semantics. */
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+#define STV_DEFAULT     0x0     /* Default visibility (see binding). */
+#define STV_INTERNAL    0x1     /* Special meaning in relocatable objects. */
+#define STV_HIDDEN      0x2     /* Not visible. */
+#define STV_PROTECTED   0x3     /* Visible but not preemptible. */
+
+/* Special symbol table indexes. */
+#define STN_UNDEF       0       /* Undefined symbol index. */
+
+/* Symbol versioning flags. */
+#define VER_DEF_CURRENT 1
+#define VER_DEF_IDX(x)  VER_NDX(x)
+
+#define VER_FLG_BASE    0x01
+#define VER_FLG_WEAK    0x02
+
+#define VER_NEED_CURRENT        1
+#define VER_NEED_WEAK   (1u << 15)
+#define VER_NEED_HIDDEN VER_NDX_HIDDEN
+#define VER_NEED_IDX(x) VER_NDX(x)
+
+#define VER_NDX_LOCAL   0
+#define VER_NDX_GLOBAL  1
+#define VER_NDX_GIVEN   2
+
+#define VER_NDX_HIDDEN  (1u << 15)
+#define VER_NDX(x)      ((x) & ~(1u << 15))
+
+#define CA_SUNW_NULL    0
+#define CA_SUNW_HW_1    1               /* first hardware capabilities entry */
+#define CA_SUNW_SF_1    2               /* first software capabilities entry */
+
+/*
+ * Syminfo flag values
+ */
+#define SYMINFO_FLG_DIRECT      0x0001  /* symbol ref has direct association */
+                                        /*      to object containing defn. */
+#define SYMINFO_FLG_PASSTHRU    0x0002  /* ignored - see SYMINFO_FLG_FILTER */
+#define SYMINFO_FLG_COPY        0x0004  /* symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD    0x0008  /* object containing defn should be */
+                                        /*      lazily-loaded */
+#define SYMINFO_FLG_DIRECTBIND  0x0010  /* ref should be bound directly to */
+                                        /*      object containing defn. */
+#define SYMINFO_FLG_NOEXTDIRECT 0x0020  /* don't let an external reference */
+                                        /*      directly bind to this symbol */
+#define SYMINFO_FLG_FILTER      0x0002  /* symbol ref is associated to a */
+#define SYMINFO_FLG_AUXILIARY   0x0040  /*      standard or auxiliary filter */
+
+/*
+ * Syminfo.si_boundto values.
+ */
+#define SYMINFO_BT_SELF         0xffff  /* symbol bound to self */
+#define SYMINFO_BT_PARENT       0xfffe  /* symbol bound to parent */
+#define SYMINFO_BT_NONE         0xfffd  /* no special symbol binding */
+#define SYMINFO_BT_EXTERN       0xfffc  /* symbol defined as external */
+#define SYMINFO_BT_LOWRESERVE   0xff00  /* beginning of reserved entries */
+
+/*
+ * Syminfo version values.
+ */
+#define SYMINFO_NONE            0       /* Syminfo version */
+#define SYMINFO_CURRENT         1
+#define SYMINFO_NUM             2
+
+/*
+ * Relocation types.
+ *
+ * All machine architectures are defined here to allow tools on one to
+ * handle others.
+ */
+
+#define R_386_NONE              0       /* No relocation. */
+#define R_386_32                1       /* Add symbol value. */
+#define R_386_PC32              2       /* Add PC-relative symbol value. */
+#define R_386_GOT32             3       /* Add PC-relative GOT offset. */
+#define R_386_PLT32             4       /* Add PC-relative PLT offset. */
+#define R_386_COPY              5       /* Copy data from shared object. */
+#define R_386_GLOB_DAT          6       /* Set GOT entry to data address. */
+#define R_386_JMP_SLOT          7       /* Set GOT entry to code address. */
+#define R_386_RELATIVE          8       /* Add load address of shared object. */
+#define R_386_GOTOFF            9       /* Add GOT-relative symbol address. */
+#define R_386_GOTPC             10      /* Add PC-relative GOT table address. */
+#define R_386_TLS_TPOFF         14      /* Negative offset in static TLS block */
+#define R_386_TLS_IE            15      /* Absolute address of GOT for -ve static TLS */
+#define R_386_TLS_GOTIE         16      /* GOT entry for negative static TLS block */
+#define R_386_TLS_LE            17      /* Negative offset relative to static TLS */
+#define R_386_TLS_GD            18      /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_LDM           19      /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_GD_32         24      /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_GD_PUSH       25      /* pushl instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_CALL       26      /* call instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_POP        27      /* popl instruction for Sun ABI GD sequence */
+#define R_386_TLS_LDM_32        28      /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_LDM_PUSH      29      /* pushl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_CALL      30      /* call instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_POP       31      /* popl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDO_32        32      /* 32 bit offset from start of TLS block */
+#define R_386_TLS_IE_32         33      /* 32 bit offset to GOT static TLS offset entry */
+#define R_386_TLS_LE_32         34      /* 32 bit offset within static TLS block */
+#define R_386_TLS_DTPMOD32      35      /* GOT entry containing TLS index */
+#define R_386_TLS_DTPOFF32      36      /* GOT entry containing TLS offset */
+#define R_386_TLS_TPOFF32       37      /* GOT entry of -ve static TLS offset */
+
+/* Null relocation */
+#define R_AARCH64_NONE                          256     /* No relocation */
+/* Static AArch64 relocations */
+ /* Static data relocations */
+#define R_AARCH64_ABS64                         257     /* S + A */
+#define R_AARCH64_ABS32                         258     /* S + A */
+#define R_AARCH64_ABS16                         259     /* S + A */
+#define R_AARCH64_PREL64                        260     /* S + A - P */
+#define R_AARCH64_PREL32                        261     /* S + A - P */
+#define R_AARCH64_PREL16                        262     /* S + A - P */
+ /* Group relocations to create a 16, 32, 48, or 64 bit unsigned data value or address inline */
+#define R_AARCH64_MOVW_UABS_G0                  263     /* S + A */
+#define R_AARCH64_MOVW_UABS_G0_NC               264     /* S + A */
+#define R_AARCH64_MOVW_UABS_G1                  265     /* S + A */
+#define R_AARCH64_MOVW_UABS_G1_NC               266     /* S + A */
+#define R_AARCH64_MOVW_UABS_G2                  267     /* S + A */
+#define R_AARCH64_MOVW_UABS_G2_NC               268     /* S + A */
+#define R_AARCH64_MOVW_UABS_G3                  269     /* S + A */
+ /* Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */
+#define R_AARCH64_MOVW_SABS_G0                  270     /* S + A */
+#define R_AARCH64_MOVW_SABS_G1                  271     /* S + A */
+#define R_AARCH64_MOVW_SABS_G2                  272     /* S + A */
+ /* Relocations to generate 19, 21 and 33 bit PC-relative addresses */
+#define R_AARCH64_LD_PREL_LO19                  273     /* S + A - P */
+#define R_AARCH64_ADR_PREL_LO21                 274     /* S + A - P */
+#define R_AARCH64_ADR_PREL_PG_HI21              275     /* Page(S+A) - Page(P) */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC           276     /* Page(S+A) - Page(P) */
+#define R_AARCH64_ADD_ABS_LO12_NC               277     /* S + A */
+#define R_AARCH64_LDST8_ABS_LO12_NC             278     /* S + A */
+#define R_AARCH64_LDST16_ABS_LO12_NC            284     /* S + A */
+#define R_AARCH64_LDST32_ABS_LO12_NC            285     /* S + A */
+#define R_AARCH64_LDST64_ABS_LO12_NC            286     /* S + A */
+#define R_AARCH64_LDST128_ABS_LO12_NC           299     /* S + A */
+ /* Relocations for control-flow instructions - all offsets are a multiple of 4 */
+#define R_AARCH64_TSTBR14                       279     /* S+A-P */
+#define R_AARCH64_CONDBR19                      280     /* S+A-P */
+#define R_AARCH64_JUMP26                        282     /* S+A-P */
+#define R_AARCH64_CALL26                        283     /* S+A-P */
+ /* Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */
+#define R_AARCH64_MOVW_PREL_G0                  287     /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G0_NC               288     /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G1                  289     /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G1_NC               290     /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G2                  291     /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G2_NC               292     /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G3                  293     /* S+A-P */
+ /* Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */
+#define R_AARCH64_MOVW_GOTOFF_G0                300     /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC             301     /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G1                302     /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC             303     /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G2                304     /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC             305     /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G3                306     /* G(S)-GOT */
+ /*  GOT-relative data relocations */
+#define R_AARCH64_GOTREL64                      307     /* S+A-GOT */
+#define R_AARCH64_GOTREL32                      308     /* S+A-GOT */
+ /* GOT-relative instruction relocations */
+#define R_AARCH64_GOT_LD_PREL19                 309     /* G(S)-P */
+#define R_AARCH64_LD64_GOTOFF_LO15              310     /* G(S)-GOT */
+#define R_AARCH64_ADR_GOT_PAGE                  311     /* Page(G(S))-Page(P) */
+#define R_AARCH64_LD64_GOT_LO12_NC              312     /* G(S) */
+#define R_AARCH64_LD64_GOTPAGE_LO15             313     /* G(S)-Page(GOT) */
+/* Relocations for thread-local storage */
+ /* General Dynamic TLS relocations */
+#define R_AARCH64_TLSGD_ADR_PREL21              512     /* G(TLSIDX(S+A)) - P */
+#define R_AARCH64_TLSGD_ADR_PAGE21              513     /* Page(G(TLSIDX(S+A))) - Page(P) */
+#define R_AARCH64_TLSGD_ADD_LO12_NC             514     /* G(TLSIDX(S+A)) */
+#define R_AARCH64_TLSGD_MOVW_G1                 515     /* G(TLSIDX(S+A)) - GOT */
+#define R_AARCH64_TLSGD_MOVW_G0_NC              516     /* G(TLSIDX(S+A)) - GOT */
+ /* Local Dynamic TLS relocations */
+#define R_AARCH64_TLSLD_ADR_PREL21              517     /* G(LDM(S))) - P */
+#define R_AARCH64_TLSLD_ADR_PAGE21              518     /* Page(G(LDM(S)))-Page(P) */
+#define R_AARCH64_TLSLD_ADD_LO12_NC             519     /* G(LDM(S)) */
+#define R_AARCH64_TLSLD_MOVW_G1                 520     /* G(LDM(S)) - GOT */
+#define R_AARCH64_TLSLD_MOVW_G0_NC              521     /* G(LDM(S)) - GOT */
+#define R_AARCH64_TLSLD_LD_PREL19               522     /* G(LDM(S)) - P */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2          523     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1          524     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC       525     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0          526     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC       527     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12         528     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12         529     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC      530     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12       531     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC    532     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12      533     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC   534     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12      535     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC   536     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12      537     /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC   538     /* DTPREL(S+A) */
+ /* Initial Exec TLS relocations */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1        539     /* G(TPREL(S+A)) - GOT */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC     540     /* G(TPREL(S+A)) - GOT */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21     541     /* Page(G(TPREL(S+A))) - Page(P) */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC   542     /* G(TPREL(S+A)) */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19      543     /* G(TPREL(S+A)) - P */
+ /* Local Exec TLS relocations */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2           544     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1           545     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC        546     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0           547     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC        548     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12          549     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12          550     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC       551     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12        552     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC     553     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12       554     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC    555     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12       556     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC    557     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12       558     /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC    559     /* TPREL(S+A) */
+/* Dynamic relocations */
+ /* Dynamic relocations */
+#define R_AARCH64_COPY                          1024
+#define R_AARCH64_GLOB_DAT                      1025    /* S + A */
+#define R_AARCH64_JUMP_SLOT                     1026    /* S + A */
+#define R_AARCH64_RELATIVE                      1027    /* Delta(S) + A , Delta(P) + A */
+#define R_AARCH64_TLS_DTPREL64                  1028    /* DTPREL(S+A) */
+#define R_AARCH64_TLS_DTPMOD64                  1029    /* LDM(S) */
+#define R_AARCH64_TLS_TPREL64                   1030    /* TPREL(S+A) */
+#define R_AARCH64_TLS_DTPREL32                  1031    /* DTPREL(S+A) */
+#define R_AARCH64_TLS_DTPMOD32                  1032    /* LDM(S) */
+#define R_AARCH64_TLS_TPREL32                   1033    /* DTPREL(S+A) */
+
+#define R_ALPHA_NONE            0       /* No reloc */
+#define R_ALPHA_REFLONG         1       /* Direct 32 bit */
+#define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
+#define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
+#define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP          6       /* Add displacement to GP */
+#define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16          9       /* PC relative 16 bit */
+#define R_ALPHA_SREL32          10      /* PC relative 32 bit */
+#define R_ALPHA_SREL64          11      /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH         12      /* OP stack push */
+#define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
+#define R_ALPHA_GPVALUE         16
+#define R_ALPHA_GPRELHIGH       17
+#define R_ALPHA_GPRELLOW        18
+#define R_ALPHA_IMMED_GP_16     19
+#define R_ALPHA_IMMED_GP_HI32   20
+#define R_ALPHA_IMMED_SCN_HI32  21
+#define R_ALPHA_IMMED_BR_HI32   22
+#define R_ALPHA_IMMED_LO32      23
+#define R_ALPHA_COPY            24      /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
+#define R_ALPHA_RELATIVE        27      /* Adjust by program base */
+
+#define R_ARM_NONE              0       /* No relocation. */
+#define R_ARM_PC24              1
+#define R_ARM_ABS32             2
+#define R_ARM_REL32             3
+#define R_ARM_PC13              4
+#define R_ARM_ABS16             5
+#define R_ARM_ABS12             6
+#define R_ARM_THM_ABS5          7
+#define R_ARM_ABS8              8
+#define R_ARM_SBREL32           9
+#define R_ARM_THM_PC22          10
+#define R_ARM_THM_PC8           11
+#define R_ARM_AMP_VCALL9        12
+#define R_ARM_SWI24             13
+#define R_ARM_THM_SWI8          14
+#define R_ARM_XPC25             15
+#define R_ARM_THM_XPC22         16
+#define R_ARM_COPY              20      /* Copy data from shared object. */
+#define R_ARM_GLOB_DAT          21      /* Set GOT entry to data address. */
+#define R_ARM_JUMP_SLOT         22      /* Set GOT entry to code address. */
+#define R_ARM_RELATIVE          23      /* Add load address of shared object. */
+#define R_ARM_GOTOFF            24      /* Add GOT-relative symbol address. */
+#define R_ARM_GOTPC             25      /* Add PC-relative GOT table address. */
+#define R_ARM_GOT32             26      /* Add PC-relative GOT offset. */
+#define R_ARM_PLT32             27      /* Add PC-relative PLT offset. */
+#define R_ARM_CALL              28
+#define R_ARM_JMP24             29
+#define R_ARM_MOVW_ABS_NC       43
+#define R_ARM_MOVT_ABS          44
+#define R_ARM_THM_MOVW_ABS_NC   47
+#define R_ARM_THM_MOVT_ABS      48
+
+// Block of PC-relative relocations added to work around gcc putting
+// object relocations in static executables.
+#define R_ARM_THM_JUMP24        30
+#define R_ARM_PREL31            42
+#define R_ARM_MOVW_PREL_NC      45
+#define R_ARM_MOVT_PREL         46
+#define R_ARM_THM_MOVW_PREL_NC  49
+#define R_ARM_THM_MOVT_PREL     50
+#define R_ARM_THM_JMP6          52
+#define R_ARM_THM_ALU_PREL_11_0 53
+#define R_ARM_THM_PC12          54
+#define R_ARM_REL32_NOI         56
+#define R_ARM_ALU_PC_G0_NC      57
+#define R_ARM_ALU_PC_G0         58
+#define R_ARM_ALU_PC_G1_NC      59
+#define R_ARM_ALU_PC_G1         60
+#define R_ARM_ALU_PC_G2         61
+#define R_ARM_LDR_PC_G1         62
+#define R_ARM_LDR_PC_G2         63
+#define R_ARM_LDRS_PC_G0        64
+#define R_ARM_LDRS_PC_G1        65
+#define R_ARM_LDRS_PC_G2        66
+#define R_ARM_LDC_PC_G0         67
+#define R_ARM_LDC_PC_G1         68
+#define R_ARM_LDC_PC_G2         69
+#define R_ARM_GOT_PREL          96
+#define R_ARM_THM_JUMP11        102
+#define R_ARM_THM_JUMP8         103
+#define R_ARM_TLS_GD32          104
+#define R_ARM_TLS_LDM32         105
+#define R_ARM_TLS_IE32          107
+
+#define R_ARM_THM_JUMP19        51
+#define R_ARM_GNU_VTENTRY       100
+#define R_ARM_GNU_VTINHERIT     101
+#define R_ARM_RSBREL32          250
+#define R_ARM_THM_RPC22         251
+#define R_ARM_RREL32            252
+#define R_ARM_RABS32            253
+#define R_ARM_RPC24             254
+#define R_ARM_RBASE             255
+
+
+
+/*      Name                    Value      Field        Calculation */
+#define R_IA_64_NONE            0       /* None */
+#define R_IA_64_IMM14           0x21    /* immediate14  S + A */
+#define R_IA_64_IMM22           0x22    /* immediate22  S + A */
+#define R_IA_64_IMM64           0x23    /* immediate64  S + A */
+#define R_IA_64_DIR32MSB        0x24    /* word32 MSB   S + A */
+#define R_IA_64_DIR32LSB        0x25    /* word32 LSB   S + A */
+#define R_IA_64_DIR64MSB        0x26    /* word64 MSB   S + A */
+#define R_IA_64_DIR64LSB        0x27    /* word64 LSB   S + A */
+#define R_IA_64_GPREL22         0x2a    /* immediate22  @gprel(S + A) */
+#define R_IA_64_GPREL64I        0x2b    /* immediate64  @gprel(S + A) */
+#define R_IA_64_GPREL32MSB      0x2c    /* word32 MSB   @gprel(S + A) */
+#define R_IA_64_GPREL32LSB      0x2d    /* word32 LSB   @gprel(S + A) */
+#define R_IA_64_GPREL64MSB      0x2e    /* word64 MSB   @gprel(S + A) */
+#define R_IA_64_GPREL64LSB      0x2f    /* word64 LSB   @gprel(S + A) */
+#define R_IA_64_LTOFF22         0x32    /* immediate22  @ltoff(S + A) */
+#define R_IA_64_LTOFF64I        0x33    /* immediate64  @ltoff(S + A) */
+#define R_IA_64_PLTOFF22        0x3a    /* immediate22  @pltoff(S + A) */
+#define R_IA_64_PLTOFF64I       0x3b    /* immediate64  @pltoff(S + A) */
+#define R_IA_64_PLTOFF64MSB     0x3e    /* word64 MSB   @pltoff(S + A) */
+#define R_IA_64_PLTOFF64LSB     0x3f    /* word64 LSB   @pltoff(S + A) */
+#define R_IA_64_FPTR64I         0x43    /* immediate64  @fptr(S + A) */
+#define R_IA_64_FPTR32MSB       0x44    /* word32 MSB   @fptr(S + A) */
+#define R_IA_64_FPTR32LSB       0x45    /* word32 LSB   @fptr(S + A) */
+#define R_IA_64_FPTR64MSB       0x46    /* word64 MSB   @fptr(S + A) */
+#define R_IA_64_FPTR64LSB       0x47    /* word64 LSB   @fptr(S + A) */
+#define R_IA_64_PCREL60B        0x48    /* immediate60 form1 S + A - P */
+#define R_IA_64_PCREL21B        0x49    /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL21M        0x4a    /* immediate21 form2 S + A - P */
+#define R_IA_64_PCREL21F        0x4b    /* immediate21 form3 S + A - P */
+#define R_IA_64_PCREL32MSB      0x4c    /* word32 MSB   S + A - P */
+#define R_IA_64_PCREL32LSB      0x4d    /* word32 LSB   S + A - P */
+#define R_IA_64_PCREL64MSB      0x4e    /* word64 MSB   S + A - P */
+#define R_IA_64_PCREL64LSB      0x4f    /* word64 LSB   S + A - P */
+#define R_IA_64_LTOFF_FPTR22    0x52    /* immediate22  @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64I   0x53    /* immediate64  @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32MSB 0x54    /* word32 MSB   @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32LSB 0x55    /* word32 LSB   @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64MSB 0x56    /* word64 MSB   @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64LSB 0x57    /* word64 LSB   @ltoff(@fptr(S + A)) */
+#define R_IA_64_SEGREL32MSB     0x5c    /* word32 MSB   @segrel(S + A) */
+#define R_IA_64_SEGREL32LSB     0x5d    /* word32 LSB   @segrel(S + A) */
+#define R_IA_64_SEGREL64MSB     0x5e    /* word64 MSB   @segrel(S + A) */
+#define R_IA_64_SEGREL64LSB     0x5f    /* word64 LSB   @segrel(S + A) */
+#define R_IA_64_SECREL32MSB     0x64    /* word32 MSB   @secrel(S + A) */
+#define R_IA_64_SECREL32LSB     0x65    /* word32 LSB   @secrel(S + A) */
+#define R_IA_64_SECREL64MSB     0x66    /* word64 MSB   @secrel(S + A) */
+#define R_IA_64_SECREL64LSB     0x67    /* word64 LSB   @secrel(S + A) */
+#define R_IA_64_REL32MSB        0x6c    /* word32 MSB   BD + A */
+#define R_IA_64_REL32LSB        0x6d    /* word32 LSB   BD + A */
+#define R_IA_64_REL64MSB        0x6e    /* word64 MSB   BD + A */
+#define R_IA_64_REL64LSB        0x6f    /* word64 LSB   BD + A */
+#define R_IA_64_LTV32MSB        0x74    /* word32 MSB   S + A */
+#define R_IA_64_LTV32LSB        0x75    /* word32 LSB   S + A */
+#define R_IA_64_LTV64MSB        0x76    /* word64 MSB   S + A */
+#define R_IA_64_LTV64LSB        0x77    /* word64 LSB   S + A */
+#define R_IA_64_PCREL21BI       0x79    /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL22         0x7a    /* immediate22  S + A - P */
+#define R_IA_64_PCREL64I        0x7b    /* immediate64  S + A - P */
+#define R_IA_64_IPLTMSB         0x80    /* function descriptor MSB special */
+#define R_IA_64_IPLTLSB         0x81    /* function descriptor LSB speciaal */
+#define R_IA_64_SUB             0x85    /* immediate64  A - S */
+#define R_IA_64_LTOFF22X        0x86    /* immediate22  special */
+#define R_IA_64_LDXMOV          0x87    /* immediate22  special */
+#define R_IA_64_TPREL14         0x91    /* imm14        @tprel(S + A) */
+#define R_IA_64_TPREL22         0x92    /* imm22        @tprel(S + A) */
+#define R_IA_64_TPREL64I        0x93    /* imm64        @tprel(S + A) */
+#define R_IA_64_TPREL64MSB      0x96    /* word64 MSB   @tprel(S + A) */
+#define R_IA_64_TPREL64LSB      0x97    /* word64 LSB   @tprel(S + A) */
+#define R_IA_64_LTOFF_TPREL22   0x9a    /* imm22        @ltoff(@tprel(S+A)) */
+#define R_IA_64_DTPMOD64MSB     0xa6    /* word64 MSB   @dtpmod(S + A) */
+#define R_IA_64_DTPMOD64LSB     0xa7    /* word64 LSB   @dtpmod(S + A) */
+#define R_IA_64_LTOFF_DTPMOD22  0xaa    /* imm22        @ltoff(@dtpmod(S+A)) */
+#define R_IA_64_DTPREL14        0xb1    /* imm14        @dtprel(S + A) */
+#define R_IA_64_DTPREL22        0xb2    /* imm22        @dtprel(S + A) */
+#define R_IA_64_DTPREL64I       0xb3    /* imm64        @dtprel(S + A) */
+#define R_IA_64_DTPREL32MSB     0xb4    /* word32 MSB   @dtprel(S + A) */
+#define R_IA_64_DTPREL32LSB     0xb5    /* word32 LSB   @dtprel(S + A) */
+#define R_IA_64_DTPREL64MSB     0xb6    /* word64 MSB   @dtprel(S + A) */
+#define R_IA_64_DTPREL64LSB     0xb7    /* word64 LSB   @dtprel(S + A) */
+#define R_IA_64_LTOFF_DTPREL22  0xba    /* imm22        @ltoff(@dtprel(S+A)) */
+
+#define R_PPC_NONE              0       /* No relocation. */
+#define R_PPC_ADDR32            1
+#define R_PPC_ADDR24            2
+#define R_PPC_ADDR16            3
+#define R_PPC_ADDR16_LO         4
+#define R_PPC_ADDR16_HI         5
+#define R_PPC_ADDR16_HA         6
+#define R_PPC_ADDR14            7
+#define R_PPC_ADDR14_BRTAKEN    8
+#define R_PPC_ADDR14_BRNTAKEN   9
+#define R_PPC_REL24             10
+#define R_PPC_REL14             11
+#define R_PPC_REL14_BRTAKEN     12
+#define R_PPC_REL14_BRNTAKEN    13
+#define R_PPC_GOT16             14
+#define R_PPC_GOT16_LO          15
+#define R_PPC_GOT16_HI          16
+#define R_PPC_GOT16_HA          17
+#define R_PPC_PLTREL24          18
+#define R_PPC_COPY              19
+#define R_PPC_GLOB_DAT          20
+#define R_PPC_JMP_SLOT          21
+#define R_PPC_RELATIVE          22
+#define R_PPC_LOCAL24PC         23
+#define R_PPC_UADDR32           24
+#define R_PPC_UADDR16           25
+#define R_PPC_REL32             26
+#define R_PPC_PLT32             27
+#define R_PPC_PLTREL32          28
+#define R_PPC_PLT16_LO          29
+#define R_PPC_PLT16_HI          30
+#define R_PPC_PLT16_HA          31
+#define R_PPC_SDAREL16          32
+#define R_PPC_SECTOFF           33
+#define R_PPC_SECTOFF_LO        34
+#define R_PPC_SECTOFF_HI        35
+#define R_PPC_SECTOFF_HA        36
+
+/*
+ * TLS relocations
+ */
+#define R_PPC_TLS               67
+#define R_PPC_DTPMOD32          68
+#define R_PPC_TPREL16           69
+#define R_PPC_TPREL16_LO        70
+#define R_PPC_TPREL16_HI        71
+#define R_PPC_TPREL16_HA        72
+#define R_PPC_TPREL32           73
+#define R_PPC_DTPREL16          74
+#define R_PPC_DTPREL16_LO       75
+#define R_PPC_DTPREL16_HI       76
+#define R_PPC_DTPREL16_HA       77
+#define R_PPC_DTPREL32          78
+#define R_PPC_GOT_TLSGD16       79
+#define R_PPC_GOT_TLSGD16_LO    80
+#define R_PPC_GOT_TLSGD16_HI    81
+#define R_PPC_GOT_TLSGD16_HA    82
+#define R_PPC_GOT_TLSLD16       83
+#define R_PPC_GOT_TLSLD16_LO    84
+#define R_PPC_GOT_TLSLD16_HI    85
+#define R_PPC_GOT_TLSLD16_HA    86
+#define R_PPC_GOT_TPREL16       87
+#define R_PPC_GOT_TPREL16_LO    88
+#define R_PPC_GOT_TPREL16_HI    89
+#define R_PPC_GOT_TPREL16_HA    90
+
+/*
+ * The remaining relocs are from the Embedded ELF ABI, and are not in the
+ *  SVR4 ELF ABI.
+ */
+
+#define R_PPC_EMB_NADDR32       101
+#define R_PPC_EMB_NADDR16       102
+#define R_PPC_EMB_NADDR16_LO    103
+#define R_PPC_EMB_NADDR16_HI    104
+#define R_PPC_EMB_NADDR16_HA    105
+#define R_PPC_EMB_SDAI16        106
+#define R_PPC_EMB_SDA2I16       107
+#define R_PPC_EMB_SDA2REL       108
+#define R_PPC_EMB_SDA21         109
+#define R_PPC_EMB_MRKREF        110
+#define R_PPC_EMB_RELSEC16      111
+#define R_PPC_EMB_RELST_LO      112
+#define R_PPC_EMB_RELST_HI      113
+#define R_PPC_EMB_RELST_HA      114
+#define R_PPC_EMB_BIT_FLD       115
+#define R_PPC_EMB_RELSDA        116
+
+#define R_SPARC_NONE            0
+#define R_SPARC_8               1
+#define R_SPARC_16              2
+#define R_SPARC_32              3
+#define R_SPARC_DISP8           4
+#define R_SPARC_DISP16          5
+#define R_SPARC_DISP32          6
+#define R_SPARC_WDISP30         7
+#define R_SPARC_WDISP22         8
+#define R_SPARC_HI22            9
+#define R_SPARC_22              10
+#define R_SPARC_13              11
+#define R_SPARC_LO10            12
+#define R_SPARC_GOT10           13
+#define R_SPARC_GOT13           14
+#define R_SPARC_GOT22           15
+#define R_SPARC_PC10            16
+#define R_SPARC_PC22            17
+#define R_SPARC_WPLT30          18
+#define R_SPARC_COPY            19
+#define R_SPARC_GLOB_DAT        20
+#define R_SPARC_JMP_SLOT        21
+#define R_SPARC_RELATIVE        22
+#define R_SPARC_UA32            23
+#define R_SPARC_PLT32           24
+#define R_SPARC_HIPLT22         25
+#define R_SPARC_LOPLT10         26
+#define R_SPARC_PCPLT32         27
+#define R_SPARC_PCPLT22         28
+#define R_SPARC_PCPLT10         29
+#define R_SPARC_10              30
+#define R_SPARC_11              31
+#define R_SPARC_64              32
+#define R_SPARC_OLO10           33
+#define R_SPARC_HH22            34
+#define R_SPARC_HM10            35
+#define R_SPARC_LM22            36
+#define R_SPARC_PC_HH22         37
+#define R_SPARC_PC_HM10         38
+#define R_SPARC_PC_LM22         39
+#define R_SPARC_WDISP16         40
+#define R_SPARC_WDISP19         41
+#define R_SPARC_GLOB_JMP        42
+#define R_SPARC_7               43
+#define R_SPARC_5               44
+#define R_SPARC_6               45
+#define R_SPARC_DISP64          46
+#define R_SPARC_PLT64           47
+#define R_SPARC_HIX22           48
+#define R_SPARC_LOX10           49
+#define R_SPARC_H44             50
+#define R_SPARC_M44             51
+#define R_SPARC_L44             52
+#define R_SPARC_REGISTER        53
+#define R_SPARC_UA64            54
+#define R_SPARC_UA16            55
+#define R_SPARC_TLS_GD_HI22     56
+#define R_SPARC_TLS_GD_LO10     57
+#define R_SPARC_TLS_GD_ADD      58
+#define R_SPARC_TLS_GD_CALL     59
+#define R_SPARC_TLS_LDM_HI22    60
+#define R_SPARC_TLS_LDM_LO10    61
+#define R_SPARC_TLS_LDM_ADD     62
+#define R_SPARC_TLS_LDM_CALL    63
+#define R_SPARC_TLS_LDO_HIX22   64
+#define R_SPARC_TLS_LDO_LOX10   65
+#define R_SPARC_TLS_LDO_ADD     66
+#define R_SPARC_TLS_IE_HI22     67
+#define R_SPARC_TLS_IE_LO10     68
+#define R_SPARC_TLS_IE_LD       69
+#define R_SPARC_TLS_IE_LDX      70
+#define R_SPARC_TLS_IE_ADD      71
+#define R_SPARC_TLS_LE_HIX22    72
+#define R_SPARC_TLS_LE_LOX10    73
+#define R_SPARC_TLS_DTPMOD32    74
+#define R_SPARC_TLS_DTPMOD64    75
+#define R_SPARC_TLS_DTPOFF32    76
+#define R_SPARC_TLS_DTPOFF64    77
+#define R_SPARC_TLS_TPOFF32     78
+#define R_SPARC_TLS_TPOFF64     79
+
+#define R_X86_64_NONE           0       /* No relocation. */
+#define R_X86_64_64             1       /* Add 64 bit symbol value. */
+#define R_X86_64_PC32           2       /* PC-relative 32 bit signed sym value. */
+#define R_X86_64_GOT32          3       /* PC-relative 32 bit GOT offset. */
+#define R_X86_64_PLT32          4       /* PC-relative 32 bit PLT offset. */
+#define R_X86_64_COPY           5       /* Copy data from shared object. */
+#define R_X86_64_GLOB_DAT       6       /* Set GOT entry to data address. */
+#define R_X86_64_JMP_SLOT       7       /* Set GOT entry to code address. */
+#define R_X86_64_RELATIVE       8       /* Add load address of shared object. */
+#define R_X86_64_GOTPCREL       9       /* Add 32 bit signed pcrel offset to GOT. */
+#define R_X86_64_32             10      /* Add 32 bit zero extended symbol value */
+#define R_X86_64_32S            11      /* Add 32 bit sign extended symbol value */
+#define R_X86_64_16             12      /* Add 16 bit zero extended symbol value */
+#define R_X86_64_PC16           13      /* Add 16 bit signed extended pc relative symbol value */
+#define R_X86_64_8              14      /* Add 8 bit zero extended symbol value */
+#define R_X86_64_PC8            15      /* Add 8 bit signed extended pc relative symbol value */
+#define R_X86_64_DTPMOD64       16      /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64       17      /* Offset in TLS block */
+#define R_X86_64_TPOFF64        18      /* Offset in static TLS block */
+#define R_X86_64_TLSGD          19      /* PC relative offset to GD GOT entry */
+#define R_X86_64_TLSLD          20      /* PC relative offset to LD GOT entry */
+#define R_X86_64_DTPOFF32       21      /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF       22      /* PC relative offset to IE GOT entry */
+#define R_X86_64_TPOFF32        23      /* Offset in static TLS block */
+
+
+#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf
index d33c3b79f84c..ed901f9f1f86 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.fdf
@@ -128,7 +128,7 @@ [FV.FvMain]
   INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
 
   # Versatile Express FileSystem
-  INF ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+  INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
 
   #
   # USB support
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index 0fbef7e378cd..c9bb236168cf 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -118,7 +118,7 @@ [LibraryClasses.common]
 
   # RunAxf support via Dynamic Shell Command protocol
   # It uses the Shell libraries.
-  ArmShellCmdRunAxfLib|ArmPlatformPkg/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf
+  ArmShellCmdRunAxfLib|Platform/ARM/Library/ArmShellCmdRunAxf/ArmShellCmdRunAxf.inf
   ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
   FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
   SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
@@ -370,7 +370,7 @@ [PcdsFixedAtBuild.common]
   #
 
   # List of Device Paths that support BootMonFs
-  gArmPlatformTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59);VenHw(1F15DA3C-37FF-4070-B471-BB4AF12A724A)"
+  gArmBootMonFsTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59);VenHw(1F15DA3C-37FF-4070-B471-BB4AF12A724A)"
 
   #
   # ARM OS Loader
@@ -434,7 +434,7 @@ [Components.common]
   }
 
   # Versatile Express FileSystem
-  ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+  Platform/ARM/Drivers/BootMonFs/BootMonFs.inf
 
   #
   # Networking stack
diff --git a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
index 1ecdbb0b231e..8bf289f8da83 100644
--- a/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
+++ b/Platform/ARM/VExpressPkg/Drivers/ArmVExpressDxe/ArmHwDxe.inf
@@ -26,6 +26,7 @@ [Sources.common]
 [Packages]
   ArmPlatformPkg/ArmPlatformPkg.dec
   MdePkg/MdePkg.dec
+  Platform/ARM/ARM.dec
 
 [LibraryClasses]
   ArmShellCmdRunAxfLib
-- 
2.11.0



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

* [PATCH edk2-platforms v2 12/13] Platform: remove stale EBL related PCD setting
  2017-11-16 18:00 ` [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 11/13] Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2 Ard Biesheuvel
@ 2017-11-16 18:00   ` Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 13/13] Platform: switch to new PL011UartLib Ard Biesheuvel
  2 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 18:00 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Remove all gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt assignments, which
are no longer meaningful with EBL removed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/ARM/JunoPkg/ArmJuno.dsc                     | 1 -
 Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc    | 1 -
 Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc | 1 -
 Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc         | 1 -
 Platform/Hisilicon/D02/Pv660D02.dsc                  | 2 --
 Platform/Hisilicon/D03/D03.dsc                       | 2 --
 Platform/Hisilicon/D05/D05.dsc                       | 2 --
 Platform/Hisilicon/HiKey/HiKey.dsc                   | 1 -
 Platform/Marvell/Armada/Armada.dsc.inc               | 1 -
 Silicon/Hisilicon/Hisilicon.dsc.inc                  | 1 -
 10 files changed, 13 deletions(-)

diff --git a/Platform/ARM/JunoPkg/ArmJuno.dsc b/Platform/ARM/JunoPkg/ArmJuno.dsc
index 3cbacb35dae3..af6fce978efc 100644
--- a/Platform/ARM/JunoPkg/ArmJuno.dsc
+++ b/Platform/ARM/JunoPkg/ArmJuno.dsc
@@ -88,7 +88,6 @@ [PcdsFeatureFlag.common]
 
 [PcdsFixedAtBuild.common]
   gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Juno"
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmJuno"
 
   #
   # NV Storage PCDs. Use base of 0x08000000 for NOR0
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
index 4a55dac7a4a4..62d992d351af 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -94,7 +94,6 @@ [PcdsFeatureFlag.common]
 
 [PcdsFixedAtBuild.common]
   gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmVExpress-CTA15-A7"
 
   gArmPlatformTokenSpaceGuid.PcdCoreCount|5
 
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
index 829854963b30..c7710564df5e 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
@@ -85,7 +85,6 @@ [PcdsFeatureFlag.common]
 
 [PcdsFixedAtBuild.common]
   gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Fixed Virtual Platform"
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ARM-FVP"
 
   # Only one core enters UEFI, and PSCI is implemented in EL3 by ATF
   gArmPlatformTokenSpaceGuid.PcdCoreCount|1
diff --git a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
index c9bb236168cf..58edf3ea6f8a 100644
--- a/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
+++ b/Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
@@ -291,7 +291,6 @@ [PcdsFixedAtBuild.common]
   gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
 !endif
 
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"VExpress"
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
   gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
   gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/Platform/Hisilicon/D02/Pv660D02.dsc b/Platform/Hisilicon/D02/Pv660D02.dsc
index cd0fbdb56fdf..d5eb963e8f2a 100644
--- a/Platform/Hisilicon/D02/Pv660D02.dsc
+++ b/Platform/Hisilicon/D02/Pv660D02.dsc
@@ -99,8 +99,6 @@ [PcdsFeatureFlag.common]
   gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
 
 [PcdsFixedAtBuild.common]
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D02"
-
   gArmPlatformTokenSpaceGuid.PcdCoreCount|8
 
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc
index a5aa5f7fcd0a..6b141dcdcbc3 100644
--- a/Platform/Hisilicon/D03/D03.dsc
+++ b/Platform/Hisilicon/D03/D03.dsc
@@ -109,8 +109,6 @@ [PcdsFeatureFlag.common]
   gHisiTokenSpaceGuid.PcdIsItsSupported|TRUE
 
 [PcdsFixedAtBuild.common]
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D03"
-
   gArmPlatformTokenSpaceGuid.PcdCoreCount|8
 
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
diff --git a/Platform/Hisilicon/D05/D05.dsc b/Platform/Hisilicon/D05/D05.dsc
index de2d3579a494..00cf0f20d23f 100644
--- a/Platform/Hisilicon/D05/D05.dsc
+++ b/Platform/Hisilicon/D05/D05.dsc
@@ -123,8 +123,6 @@ [PcdsFeatureFlag.common]
   gHisiTokenSpaceGuid.PcdIsItsSupported|TRUE
 
 [PcdsFixedAtBuild.common]
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D05"
-
   gArmPlatformTokenSpaceGuid.PcdCoreCount|8
 
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
diff --git a/Platform/Hisilicon/HiKey/HiKey.dsc b/Platform/Hisilicon/HiKey/HiKey.dsc
index f0380ee1f929..a339eadc30ac 100644
--- a/Platform/Hisilicon/HiKey/HiKey.dsc
+++ b/Platform/Hisilicon/HiKey/HiKey.dsc
@@ -272,7 +272,6 @@ [PcdsFixedAtBuild.common]
 
   gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"hikey"
   gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Alpha"
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"HiKey"
 
   #
   # NV Storage PCDs.
diff --git a/Platform/Marvell/Armada/Armada.dsc.inc b/Platform/Marvell/Armada/Armada.dsc.inc
index 77f08c419417..0c873fb112ac 100644
--- a/Platform/Marvell/Armada/Armada.dsc.inc
+++ b/Platform/Marvell/Armada/Armada.dsc.inc
@@ -239,7 +239,6 @@ [PcdsFixedAtBuild.common]
   gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
   gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
 
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"Marvell>> "
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
   gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
   gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index 318c4ffeb250..50df0679f8dd 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -254,7 +254,6 @@ [PcdsFeatureFlag.common]
 [PcdsFixedAtBuild.common]
   gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
 
-  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"VExpress"
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|44
   gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
-- 
2.11.0



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

* [PATCH edk2-platforms v2 13/13] Platform: switch to new PL011UartLib
  2017-11-16 18:00 ` [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 11/13] Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2 Ard Biesheuvel
  2017-11-16 18:00   ` [PATCH edk2-platforms v2 12/13] Platform: remove stale EBL related PCD setting Ard Biesheuvel
@ 2017-11-16 18:00   ` Ard Biesheuvel
  2 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-16 18:00 UTC (permalink / raw)
  To: edk2-devel, leif.lindholm; +Cc: Ard Biesheuvel

Switch to the new version of PL011UartLib which supersedes the one
residing in Drivers/ inappropriately.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Platform/AMD/OverdriveBoard/OverdriveBoard.dsc               | 2 +-
 Platform/Hisilicon/HiKey/HiKey.dsc                           | 2 +-
 Platform/LeMaker/CelloBoard/CelloBoard.dsc                   | 2 +-
 Platform/Socionext/DeveloperBox/DeveloperBox.dsc             | 2 +-
 Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc | 2 +-
 Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc  | 2 +-
 Silicon/Hisilicon/Hisilicon.dsc.inc                          | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc b/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
index 7258daa76094..2cc71d499ece 100644
--- a/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
+++ b/Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
@@ -106,7 +106,7 @@ [LibraryClasses.common]
   UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
 
   # ARM PL011 UART Driver
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
 
   #
diff --git a/Platform/Hisilicon/HiKey/HiKey.dsc b/Platform/Hisilicon/HiKey/HiKey.dsc
index a339eadc30ac..97811eb8d991 100644
--- a/Platform/Hisilicon/HiKey/HiKey.dsc
+++ b/Platform/Hisilicon/HiKey/HiKey.dsc
@@ -84,7 +84,7 @@ [LibraryClasses.common]
   UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
   UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
 
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
   RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
   TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
diff --git a/Platform/LeMaker/CelloBoard/CelloBoard.dsc b/Platform/LeMaker/CelloBoard/CelloBoard.dsc
index 30b080495639..33e9ebee3255 100644
--- a/Platform/LeMaker/CelloBoard/CelloBoard.dsc
+++ b/Platform/LeMaker/CelloBoard/CelloBoard.dsc
@@ -102,7 +102,7 @@ [LibraryClasses.common]
   UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
 
   # ARM PL011 UART Driver
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
 
   #
diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
index 21987d890997..2405ffaf3dc0 100644
--- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
+++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
@@ -115,7 +115,7 @@ [LibraryClasses.common]
   DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
   DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
 
   HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
   TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
diff --git a/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc b/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
index 6c9afa518fdf..5635286dbfc4 100644
--- a/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
+++ b/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
@@ -115,7 +115,7 @@ [LibraryClasses.common]
   DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
   DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
 
   HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
   TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
diff --git a/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc b/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
index 5cbf3628fb89..5352fc4e5575 100644
--- a/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
+++ b/Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
@@ -104,7 +104,7 @@ [LibraryClasses.common]
   UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
 
   # ARM PL011 UART Driver
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
   SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
 
   #
diff --git a/Silicon/Hisilicon/Hisilicon.dsc.inc b/Silicon/Hisilicon/Hisilicon.dsc.inc
index 50df0679f8dd..761df16f4e12 100644
--- a/Silicon/Hisilicon/Hisilicon.dsc.inc
+++ b/Silicon/Hisilicon/Hisilicon.dsc.inc
@@ -65,7 +65,7 @@ [LibraryClasses.common]
   ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
 
   # ARM PL011 UART Driver
-  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
 
   SerialPortLib|Silicon/Hisilicon/Library/Dw8250SerialPortLib/Dw8250SerialPortLib.inf
   TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
-- 
2.11.0



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

* Re: [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms
  2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
                   ` (9 preceding siblings ...)
  2017-11-16 18:00 ` [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references Ard Biesheuvel
@ 2017-11-25 12:12 ` Leif Lindholm
  2017-11-26 10:36   ` Ard Biesheuvel
  2017-12-04 17:23   ` Leif Lindholm
  10 siblings, 2 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-11-25 12:12 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: edk2-devel

On Thu, Nov 16, 2017 at 05:58:30PM +0000, Ard Biesheuvel wrote:
> This is mostly a preparatory series that will allow us to get rid of a lot
> of code that is specific to only a single ARM development platform out of
> the main EDK2 tree.
> 
> First of all, it removes a couple of false dependencies of various platforms
> on libraries that are no longer used, or not actually used by the platform
> in question. Patches #5, #6 and #11 move the bulk of the support for ARM
> development platforms into edk2-platforms.
> 
> Ard Biesheuvel (13):
>   Platform: remove bogus ArmPlatformSecExtraActionLib references
>   Platform: remove bogus ArmTrustedMonitorLib references
>   Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference
>   Platform/Hisilicon: remove bogus VExpress dependencies
>   Platform/ARM/Juno: import ArmJunoPkg from EDK2
>   Platform/ARM/VExpress: import VExpressPkg from EDK2

Again, please hold off on this one (import VExpressPkg) for a few days.
As far as I can see, the subsequent ones would not be affected and so
can be merged without conflict.

For all other patches in series:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

>   Platform/ARM: remove outdated SP804 TimerLib reference
>   Platform/Hisilicon: remove SP804 PCD definitions
>   Platform: remove references to EBL libraries
>   Platform: remove stale PL35xSmcLib references
>   Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2
>   Platform: remove stale EBL related PCD setting
>   Platform: switch to new PL011UartLib


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

* Re: [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms
  2017-11-25 12:12 ` [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Leif Lindholm
@ 2017-11-26 10:36   ` Ard Biesheuvel
  2017-12-04 17:23   ` Leif Lindholm
  1 sibling, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2017-11-26 10:36 UTC (permalink / raw)
  To: Leif Lindholm; +Cc: edk2-devel@lists.01.org

On 25 November 2017 at 12:12, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Thu, Nov 16, 2017 at 05:58:30PM +0000, Ard Biesheuvel wrote:
>> This is mostly a preparatory series that will allow us to get rid of a lot
>> of code that is specific to only a single ARM development platform out of
>> the main EDK2 tree.
>>
>> First of all, it removes a couple of false dependencies of various platforms
>> on libraries that are no longer used, or not actually used by the platform
>> in question. Patches #5, #6 and #11 move the bulk of the support for ARM
>> development platforms into edk2-platforms.
>>
>> Ard Biesheuvel (13):
>>   Platform: remove bogus ArmPlatformSecExtraActionLib references
>>   Platform: remove bogus ArmTrustedMonitorLib references
>>   Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference
>>   Platform/Hisilicon: remove bogus VExpress dependencies
>>   Platform/ARM/Juno: import ArmJunoPkg from EDK2
>>   Platform/ARM/VExpress: import VExpressPkg from EDK2
>
> Again, please hold off on this one (import VExpressPkg) for a few days.
> As far as I can see, the subsequent ones would not be affected and so
> can be merged without conflict.
>

With the exception of the BootMonFs/ArmShellCmdRunAxf migration, which
depends on it.

> For all other patches in series:
> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
>

Thanks. Remaining patches pushed as 89a256625016..4591a21d5a8e

>>   Platform/ARM: remove outdated SP804 TimerLib reference
>>   Platform/Hisilicon: remove SP804 PCD definitions
>>   Platform: remove references to EBL libraries
>>   Platform: remove stale PL35xSmcLib references
>>   Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2
>>   Platform: remove stale EBL related PCD setting
>>   Platform: switch to new PL011UartLib


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

* Re: [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms
  2017-11-25 12:12 ` [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Leif Lindholm
  2017-11-26 10:36   ` Ard Biesheuvel
@ 2017-12-04 17:23   ` Leif Lindholm
  1 sibling, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-12-04 17:23 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: edk2-devel

On Sat, Nov 25, 2017 at 12:12:45PM +0000, Leif Lindholm wrote:
> On Thu, Nov 16, 2017 at 05:58:30PM +0000, Ard Biesheuvel wrote:
> > This is mostly a preparatory series that will allow us to get rid of a lot
> > of code that is specific to only a single ARM development platform out of
> > the main EDK2 tree.
> > 
> > First of all, it removes a couple of false dependencies of various platforms
> > on libraries that are no longer used, or not actually used by the platform
> > in question. Patches #5, #6 and #11 move the bulk of the support for ARM
> > development platforms into edk2-platforms.
> > 
> > Ard Biesheuvel (13):
> >   Platform: remove bogus ArmPlatformSecExtraActionLib references
> >   Platform: remove bogus ArmTrustedMonitorLib references
> >   Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference
> >   Platform/Hisilicon: remove bogus VExpress dependencies
> >   Platform/ARM/Juno: import ArmJunoPkg from EDK2
> >   Platform/ARM/VExpress: import VExpressPkg from EDK2
> 
> Again, please hold off on this one (import VExpressPkg) for a few days.
> As far as I can see, the subsequent ones would not be affected and so
> can be merged without conflict.

OK, I don't think we need to hold off on this any longer:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> >   Platform/ARM: remove outdated SP804 TimerLib reference
> >   Platform/Hisilicon: remove SP804 PCD definitions
> >   Platform: remove references to EBL libraries
> >   Platform: remove stale PL35xSmcLib references
> >   Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2
> >   Platform: remove stale EBL related PCD setting
> >   Platform: switch to new PL011UartLib


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

end of thread, other threads:[~2017-12-04 17:19 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-16 17:58 [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 01/13] Platform: remove bogus ArmPlatformSecExtraActionLib references Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 02/13] Platform: remove bogus ArmTrustedMonitorLib references Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 03/13] Platform/ArmVExpress-FVP: remove bogus ArmPlatformSecLib reference Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 04/13] Platform/Hisilicon: remove bogus VExpress dependencies Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 05/13] Platform/ARM/Juno: import ArmJunoPkg from EDK2 Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 06/13] Platform/ARM/VExpress: import VExpressPkg " Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 07/13] Platform/ARM: remove outdated SP804 TimerLib reference Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 08/13] Platform/Hisilicon: remove SP804 PCD definitions Ard Biesheuvel
2017-11-16 17:58 ` [PATCH edk2-platforms v2 09/13] Platform: remove references to EBL libraries Ard Biesheuvel
2017-11-16 18:00 ` [PATCH edk2-platforms v2 10/13] Platform: remove stale PL35xSmcLib references Ard Biesheuvel
2017-11-16 18:00   ` [PATCH edk2-platforms v2 11/13] Platform/ARM: import BootMonFs and ArmShellCmdRunAxf from EDK2 Ard Biesheuvel
2017-11-16 18:00   ` [PATCH edk2-platforms v2 12/13] Platform: remove stale EBL related PCD setting Ard Biesheuvel
2017-11-16 18:00   ` [PATCH edk2-platforms v2 13/13] Platform: switch to new PL011UartLib Ard Biesheuvel
2017-11-25 12:12 ` [PATCH edk2-platforms v2 00/13] Move ArmPlatformPkg stuff into edk2-platforms Leif Lindholm
2017-11-26 10:36   ` Ard Biesheuvel
2017-12-04 17:23   ` Leif Lindholm

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