* [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