diff mbox

[edk2,v4,11/16] ArmVirtualizationPkg: add ArmVirtualizationPlatformLib library

Message ID 1409235244-25783-12-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel Aug. 28, 2014, 2:13 p.m. UTC
This is an implementation of ArmPlatformLib that discovers the size of system
DRAM from a device tree blob located at the address passed in
gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress, which should equal the value in
gArmTokenSpaceGuid.PcdSystemMemoryBase.

As the device tree blob is passed in system DRAM, this library can only be used
if sufficient DRAM is available (>= 128 MB) and if not using shadowed NOR. The
reason for this is that it makes it easier to guarantee that such a device tree
blob at base of DRAM will not be clobbered before we get a chance to preserve it.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Casadevall <michael.casadevall@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 .../AARCH64/VirtHelper.S                           |  86 ++++++++++++
 .../ArmVirtualizationPlatformLib/ARM/VirtHelper.S  |  81 +++++++++++
 .../ArmVirtualizationPlatformLib.inf               |  60 ++++++++
 .../Library/ArmVirtualizationPlatformLib/Virt.c    | 151 +++++++++++++++++++++
 .../Library/ArmVirtualizationPlatformLib/VirtMem.c | 107 +++++++++++++++
 5 files changed, 485 insertions(+)
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
 create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c

Comments

Laszlo Ersek Aug. 28, 2014, 10 p.m. UTC | #1
On 08/28/14 16:13, Ard Biesheuvel wrote:
> This is an implementation of ArmPlatformLib that discovers the size of system
> DRAM from a device tree blob located at the address passed in
> gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress, which should equal the value in
> gArmTokenSpaceGuid.PcdSystemMemoryBase.
> 
> As the device tree blob is passed in system DRAM, this library can only be used
> if sufficient DRAM is available (>= 128 MB) and if not using shadowed NOR. The
> reason for this is that it makes it easier to guarantee that such a device tree
> blob at base of DRAM will not be clobbered before we get a chance to preserve it.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Michael Casadevall <michael.casadevall@linaro.org>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../AARCH64/VirtHelper.S                           |  86 ++++++++++++
>  .../ArmVirtualizationPlatformLib/ARM/VirtHelper.S  |  81 +++++++++++
>  .../ArmVirtualizationPlatformLib.inf               |  60 ++++++++
>  .../Library/ArmVirtualizationPlatformLib/Virt.c    | 151 +++++++++++++++++++++
>  .../Library/ArmVirtualizationPlatformLib/VirtMem.c | 107 +++++++++++++++
>  5 files changed, 485 insertions(+)
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
>  create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c
> 
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S
> new file mode 100644
> index 000000000000..fd0bfe4afa2d
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S
> @@ -0,0 +1,86 @@
> +#
> +#  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 <Base.h>
> +#include <Library/ArmLib.h>
> +#include <Library/PcdLib.h>
> +#include <AutoGen.h>
> +
> +.text
> +.align 2
> +
> +GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
> +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
> +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
> +GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
> +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
> +GCC_ASM_EXPORT(ArmGetPhysAddrTop)
> +
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
> +
> +ASM_PFX(ArmPlatformPeiBootAction):
> +  ret
> +
> +//UINTN
> +//ArmPlatformGetPrimaryCoreMpId (
> +//  VOID
> +//  );
> +ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
> +  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
> +  ldrh   w0, [x0]
> +  ret
> +
> +# IN None
> +# OUT x0 = number of cores present in the system
> +ASM_PFX(ArmGetCpuCountPerCluster):
> +  mov   x0, #1
> +  ret
> +
> +//UINTN
> +//ArmPlatformIsPrimaryCore (
> +//  IN UINTN MpId
> +//  );
> +ASM_PFX(ArmPlatformIsPrimaryCore):
> +  mov   x0, #1
> +  ret
> +
> +//UINTN
> +//ArmPlatformGetCorePosition (
> +//  IN UINTN MpId
> +//  );
> +// With this function: CorePos = (ClusterId * 4) + CoreId
> +ASM_PFX(ArmPlatformGetCorePosition):
> +  and   x1, x0, #ARM_CORE_MASK
> +  and   x0, x0, #ARM_CLUSTER_MASK
> +  add   x0, x1, x0, LSR #6
> +  ret
> +
> +//EFI_PHYSICAL_ADDRESS
> +//GetPhysAddrTop (
> +//  VOID
> +//  );
> +ASM_PFX(ArmGetPhysAddrTop):
> +  mrs   x0, id_aa64mmfr0_el1
> +  adr   x1, .LPARanges
> +  and   x0, x0, #7
> +  ldrb  w1, [x1, x0]
> +  mov   x0, #1
> +  lsl   x0, x0, x1
> +  ret
> +.LPARanges:
> +  .byte 32, 36, 40, 42, 44, 48, -1, -1
> +
> +ASM_FUNCTION_REMOVE_IF_UNREFERENCED
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S
> new file mode 100644
> index 000000000000..dc79b982b598
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S
> @@ -0,0 +1,81 @@
> +#
> +#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +#  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution.  The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#
> +
> +#include <AsmMacroIoLib.h>
> +#include <Base.h>
> +#include <Library/ArmLib.h>
> +#include <Library/PcdLib.h>
> +#include <AutoGen.h>
> +
> +.text
> +.align 2
> +
> +GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
> +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
> +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
> +GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
> +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
> +GCC_ASM_EXPORT(ArmGetPhysAddrTop)
> +
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
> +
> +ASM_PFX(ArmPlatformPeiBootAction):
> +  bx    lr
> +
> +//UINTN
> +//ArmPlatformGetPrimaryCoreMpId (
> +//  VOID
> +//  );
> +ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
> +  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)
> +  ldr    r0, [r0]
> +  bx     lr
> +
> +# IN None
> +# OUT r0 = number of cores present in the system
> +ASM_PFX(ArmGetCpuCountPerCluster):
> +  mov   r0, #1
> +  bx    lr
> +
> +//UINTN
> +//ArmPlatformIsPrimaryCore (
> +//  IN UINTN MpId
> +//  );
> +ASM_PFX(ArmPlatformIsPrimaryCore):
> +  mov   r0, #1
> +  bx    lr
> +
> +//UINTN
> +//ArmPlatformGetCorePosition (
> +//  IN UINTN MpId
> +//  );
> +// With this function: CorePos = (ClusterId * 4) + CoreId
> +ASM_PFX(ArmPlatformGetCorePosition):
> +  and   r1, r0, #ARM_CORE_MASK
> +  and   r0, r0, #ARM_CLUSTER_MASK
> +  add   r0, r1, r0, LSR #6
> +  bx    lr
> +
> +//EFI_PHYSICAL_ADDRESS
> +//GetPhysAddrTop (
> +//  VOID
> +//  );
> +ASM_PFX(ArmGetPhysAddrTop):
> +  mov   r0, #0x00000000
> +  mov   r1, #0x10000
> +  bx    lr
> +
> +ASM_FUNCTION_REMOVE_IF_UNREFERENCED
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
> new file mode 100644
> index 000000000000..e7d6ec536dcd
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
> @@ -0,0 +1,60 @@
> +#/* @file
> +#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +#  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution.  The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#*/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = ArmVirtualizationPlatformLib
> +  FILE_GUID                      = 00214cc1-06d1-45fe-9700-dca5726ad7bf
> +  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
> +  PrintLib
> +  FdtLib
> +
> +[Sources.common]
> +  Virt.c
> +  VirtMem.c
> +
> +[Sources.AARCH64]
> +  AARCH64/VirtHelper.S      | GCC
> +
> +[Sources.ARM]
> +  ARM/VirtHelper.S          | GCC
> +
> +[FeaturePcd]
> +  gEmbeddedTokenSpaceGuid.PcdCacheEnable
> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdSystemMemorySize
> +  gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress
> +
> +[FixedPcd]
> +  gArmPlatformTokenSpaceGuid.PcdCoreCount
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
> +  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
> +  gArmTokenSpaceGuid.PcdArmPrimaryCore
> +  gArmTokenSpaceGuid.PcdFdBaseAddress
> +  gArmTokenSpaceGuid.PcdFdSize
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> new file mode 100644
> index 000000000000..a02712274dd3
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
> @@ -0,0 +1,151 @@
> +/** @file
> +*
> +*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +*  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +* 
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of the BSD License
> +*  which accompanies this distribution.  The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#include <Library/IoLib.h>
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <ArmPlatform.h>
> +#include <libfdt.h>
> +
> +/**
> +  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
> +  )
> +{
> +  //
> +  // We are relying on ArmPlatformInitializeSystemMemory () being called from
> +  // InitializeMemory (), which only occurs if the following feature is disabled
> +  //
> +  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Initialize the system (or sometimes called permanent) memory
> +
> +  This memory is generally represented by the DRAM.
> +
> +**/
> +VOID
> +ArmPlatformInitializeSystemMemory (
> +  VOID
> +  )
> +{
> +  VOID    *DeviceTreeBase;
> +  INT32   Node, Prev;
> +  UINT64  NewBase;
> +  UINT64  NewSize;
> +
> +  NewBase = 0;
> +  NewSize = 0;
> +
> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
> +  ASSERT (DeviceTreeBase != NULL);
> +
> +  //
> +  // Make sure we have a valid device tree blob
> +  //
> +  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
> +
> +  //
> +  // Look for a memory node
> +  //
> +  for (Prev = 0;; Prev = Node) {
> +    CONST CHAR8  *Type;
> +    INT32         Len;
> +
> +    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
> +    if (Node < 0) {
> +      break;
> +    }
> +
> +    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
> +    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
> +      CONST UINT64 *RegProp;
> +
> +      //
> +      // Get the 'reg' property of this node. For now, we will assume
> +      // two 8 byte quantities for base and size, respectively.
> +      //
> +      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
> +      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
> +
> +        NewBase = fdt64_to_cpu (RegProp[0]);
> +        NewSize = fdt64_to_cpu (RegProp[1]);
> +
> +        //
> +        // Make sure the start of DRAM matches our expectation
> +        //
> +        ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
> +        PcdSet64 (PcdSystemMemorySize, NewSize);
> +
> +        DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
> +               __FUNCTION__, NewBase, NewBase + NewSize - 1));
> +      } else {
> +        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
> +               __FUNCTION__));
> +      }
> +      break;
> +    }
> +  }
> +  //
> +  // We need to make sure that the machine we are running on has at least
> +  // 128 MB of memory configured, and is currently executing this binary from
> +  // NOR flash. This prevents a device tree image in DRAM from getting
> +  // clobbered when our caller installs permanent PEI RAM, before we have a
> +  // chance of marking its location as reserved or copy it to a freshly
> +  // allocated block in the permanent PEI RAM in the platform PEIM.
> +  //
> +  ASSERT (NewSize >= SIZE_128MB);
> +  ASSERT (
> +    (UINT64)PcdGet32 (PcdFdBaseAddress) +
> +     (UINT64)PcdGet32 (PcdFdSize) <= NewBase ||
> +    (UINT64)PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize);
> +}
> +
> +VOID
> +ArmPlatformGetPlatformPpiList (
> +  OUT UINTN                   *PpiListSize,
> +  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
> +  )
> +{
> +  *PpiListSize = 0;
> +  *PpiList = NULL;
> +}
> diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c
> new file mode 100644
> index 000000000000..153c1d20e908
> --- /dev/null
> +++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c
> @@ -0,0 +1,107 @@
> +/** @file
> +*
> +*  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of the BSD License
> +*  which accompanies this distribution.  The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/ArmPlatformGlobalVariableLib.h>
> +#include <ArmPlatform.h>
> +
> +// Number of Virtual Memory Map Descriptors
> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          4
> +
> +// DDR attributes
> +#define DDR_ATTRIBUTES_CACHED    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
> +#define DDR_ATTRIBUTES_UNCACHED  ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
> +
> +EFI_PHYSICAL_ADDRESS
> +ArmGetPhysAddrTop (
> +  VOID
> +  );
> +
> +/**
> +  Return the Virtual Memory Map of your platform
> +
> +  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
> +  on your platform.
> +
> +  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR 
> +                                    describing a Physical-to-Virtual Memory
> +                                    mapping. This array must be ended by a
> +                                    zero-filled entry
> +
> +**/
> +VOID
> +ArmPlatformGetVirtualMemoryMap (
> +  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
> +  )
> +{
> +  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
> +  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
> +
> +  ASSERT (VirtualMemoryMap != NULL);
> +
> +  VirtualMemoryTable = AllocatePages (
> +                         EFI_SIZE_TO_PAGES (
> +                           sizeof (ARM_MEMORY_REGION_DESCRIPTOR)
> +                           * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
> +                           )
> +                         );
> +
> +  if (VirtualMemoryTable == NULL) {
> +    DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", __FUNCTION__));
> +    return;
> +  }
> +
> +  if (FeaturePcdGet (PcdCacheEnable) == TRUE) {
> +      CacheAttributes = DDR_ATTRIBUTES_CACHED;
> +  } else {
> +      CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
> +  }
> +
> +  // System DRAM
> +  VirtualMemoryTable[0].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
> +  VirtualMemoryTable[0].VirtualBase  = VirtualMemoryTable[0].PhysicalBase;
> +  VirtualMemoryTable[0].Length       = PcdGet64 (PcdSystemMemorySize);
> +  VirtualMemoryTable[0].Attributes   = CacheAttributes;
> +
> +  DEBUG ((EFI_D_INFO, "%a: Dumping System DRAM Memory Map:\n"
> +      "\tPhysicalBase: 0x%lX\n"
> +      "\tVirtualBase: 0x%lX\n"
> +      "\tLength: 0x%lX\n",
> +      __FUNCTION__,
> +      VirtualMemoryTable[0].PhysicalBase,
> +      VirtualMemoryTable[0].VirtualBase,
> +      VirtualMemoryTable[0].Length));
> +
> +  // Peripheral space before DRAM
> +  VirtualMemoryTable[1].PhysicalBase = 0x0;
> +  VirtualMemoryTable[1].VirtualBase  = 0x0;
> +  VirtualMemoryTable[1].Length       = VirtualMemoryTable[0].PhysicalBase;
> +  VirtualMemoryTable[1].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  // Peripheral space after DRAM
> +  VirtualMemoryTable[2].PhysicalBase = VirtualMemoryTable[0].Length + VirtualMemoryTable[1].Length;
> +  VirtualMemoryTable[2].VirtualBase  = VirtualMemoryTable[2].PhysicalBase;
> +  VirtualMemoryTable[2].Length       = ArmGetPhysAddrTop () - VirtualMemoryTable[2].PhysicalBase;
> +  VirtualMemoryTable[2].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  // End of Table
> +  ZeroMem (&VirtualMemoryTable[3], sizeof (ARM_MEMORY_REGION_DESCRIPTOR));
> +
> +  *VirtualMemoryMap = VirtualMemoryTable;
> +}
> 

Great! I'd like to give my R-b, but I can only manage an A-b, due to the
ARM assembly, which is Greek to me, sorry. Hence only:

Acked-by: Laszlo Ersek <lersek@redhat.com>

Thank you!
Laszlo

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
Olivier Martin Sept. 1, 2014, 4:32 p.m. UTC | #2
Some trailing space issues:
-
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Vir
tMem.c
-
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Vir
t.c

And line endings:
-
ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM
/VirtHelper.S

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: 28 August 2014 15:14
> To: lersek@redhat.com; Olivier Martin; edk2-
> devel@lists.sourceforge.net; peter.maydell@linaro.org;
> christoffer.dall@linaro.org; drjones@redhat.com;
> ilias.biris@linaro.org; leif.lindholm@linaro.org
> Cc: Ard Biesheuvel; Michael Casadevall
> Subject: [PATCH v4 11/16] ArmVirtualizationPkg: add
> ArmVirtualizationPlatformLib library
> 
> This is an implementation of ArmPlatformLib that discovers the size of
> system
> DRAM from a device tree blob located at the address passed in
> gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress, which should equal the
> value in
> gArmTokenSpaceGuid.PcdSystemMemoryBase.
> 
> As the device tree blob is passed in system DRAM, this library can only
> be used
> if sufficient DRAM is available (>= 128 MB) and if not using shadowed
> NOR. The
> reason for this is that it makes it easier to guarantee that such a
> device tree
> blob at base of DRAM will not be clobbered before we get a chance to
> preserve it.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Michael Casadevall <michael.casadevall@linaro.org>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  .../AARCH64/VirtHelper.S                           |  86 ++++++++++++
>  .../ArmVirtualizationPlatformLib/ARM/VirtHelper.S  |  81 +++++++++++
>  .../ArmVirtualizationPlatformLib.inf               |  60 ++++++++
>  .../Library/ArmVirtualizationPlatformLib/Virt.c    | 151
> +++++++++++++++++++++
>  .../Library/ArmVirtualizationPlatformLib/VirtMem.c | 107
> +++++++++++++++
>  5 files changed, 485 insertions(+)
>  create mode 100644
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi
> b/AARCH64/VirtHelper.S
>  create mode 100644
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi
> b/ARM/VirtHelper.S
>  create mode 100644
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi
> b/ArmVirtualizationPlatformLib.inf
>  create mode 100644
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi
> b/Virt.c
>  create mode 100644
> ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLi
> b/VirtMem.c
> 
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/AARCH64/VirtHelper.S
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/AARCH64/VirtHelper.S
> new file mode 100644
> index 000000000000..fd0bfe4afa2d
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/AARCH64/VirtHelper.S
> @@ -0,0 +1,86 @@
> +#
> +#  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 <Base.h>
> +#include <Library/ArmLib.h>
> +#include <Library/PcdLib.h>
> +#include <AutoGen.h>
> +
> +.text
> +.align 2
> +
> +GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
> +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
> +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
> +GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
> +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
> +GCC_ASM_EXPORT(ArmGetPhysAddrTop)
> +
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
> +
> +ASM_PFX(ArmPlatformPeiBootAction):
> +  ret
> +
> +//UINTN
> +//ArmPlatformGetPrimaryCoreMpId (
> +//  VOID
> +//  );
> +ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
> +  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
> +  ldrh   w0, [x0]
> +  ret
> +
> +# IN None
> +# OUT x0 = number of cores present in the system
> +ASM_PFX(ArmGetCpuCountPerCluster):
> +  mov   x0, #1
> +  ret

This function is not used.


> +
> +//UINTN
> +//ArmPlatformIsPrimaryCore (
> +//  IN UINTN MpId
> +//  );
> +ASM_PFX(ArmPlatformIsPrimaryCore):
> +  mov   x0, #1
> +  ret
> +
> +//UINTN
> +//ArmPlatformGetCorePosition (
> +//  IN UINTN MpId
> +//  );
> +// With this function: CorePos = (ClusterId * 4) + CoreId
> +ASM_PFX(ArmPlatformGetCorePosition):
> +  and   x1, x0, #ARM_CORE_MASK
> +  and   x0, x0, #ARM_CLUSTER_MASK
> +  add   x0, x1, x0, LSR #6
> +  ret
> +
> +//EFI_PHYSICAL_ADDRESS
> +//GetPhysAddrTop (
> +//  VOID
> +//  );
> +ASM_PFX(ArmGetPhysAddrTop):
> +  mrs   x0, id_aa64mmfr0_el1
> +  adr   x1, .LPARanges
> +  and   x0, x0, #7
> +  ldrb  w1, [x1, x0]
> +  mov   x0, #1
> +  lsl   x0, x0, x1
> +  ret
> +.LPARanges:
> +  .byte 32, 36, 40, 42, 44, 48, -1, -1

Is this list of bytes a secret code?
Would you mind to add a comment above the list of memory address space size?



> +
> +ASM_FUNCTION_REMOVE_IF_UNREFERENCED
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ARM/VirtHelper.S
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ARM/VirtHelper.S
> new file mode 100644
> index 000000000000..dc79b982b598
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ARM/VirtHelper.S
> @@ -0,0 +1,81 @@
> +#
> +#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +#  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of
> the BSD License
> +#  which accompanies this distribution.  The full text of the license
> may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS
> OR IMPLIED.
> +#
> +#
> +
> +#include <AsmMacroIoLib.h>
> +#include <Base.h>
> +#include <Library/ArmLib.h>
> +#include <Library/PcdLib.h>
> +#include <AutoGen.h>
> +
> +.text
> +.align 2
> +
> +GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
> +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
> +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
> +GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
> +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
> +GCC_ASM_EXPORT(ArmGetPhysAddrTop)
> +
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
> +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
> +
> +ASM_PFX(ArmPlatformPeiBootAction):
> +  bx    lr
> +
> +//UINTN
> +//ArmPlatformGetPrimaryCoreMpId (
> +//  VOID
> +//  );
> +ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
> +  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)
> +  ldr    r0, [r0]
> +  bx     lr
> +
> +# IN None
> +# OUT r0 = number of cores present in the system
> +ASM_PFX(ArmGetCpuCountPerCluster):
> +  mov   r0, #1
> +  bx    lr

This function is not used.


> +
> +//UINTN
> +//ArmPlatformIsPrimaryCore (
> +//  IN UINTN MpId
> +//  );
> +ASM_PFX(ArmPlatformIsPrimaryCore):
> +  mov   r0, #1
> +  bx    lr
> +
> +//UINTN
> +//ArmPlatformGetCorePosition (
> +//  IN UINTN MpId
> +//  );
> +// With this function: CorePos = (ClusterId * 4) + CoreId
> +ASM_PFX(ArmPlatformGetCorePosition):
> +  and   r1, r0, #ARM_CORE_MASK
> +  and   r0, r0, #ARM_CLUSTER_MASK
> +  add   r0, r1, r0, LSR #6
> +  bx    lr
> +
> +//EFI_PHYSICAL_ADDRESS
> +//GetPhysAddrTop (
> +//  VOID
> +//  );
> +ASM_PFX(ArmGetPhysAddrTop):
> +  mov   r0, #0x00000000
> +  mov   r1, #0x10000
> +  bx    lr
> +
> +ASM_FUNCTION_REMOVE_IF_UNREFERENCED
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> new file mode 100644
> index 000000000000..e7d6ec536dcd
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/ArmVirtualizationPlatformLib.inf
> @@ -0,0 +1,60 @@
> +#/* @file
> +#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +#  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of
> the BSD License
> +#  which accompanies this distribution.  The full text of the license
> may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS
> OR IMPLIED.
> +#
> +#*/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = ArmVirtualizationPlatformLib
> +  FILE_GUID                      = 00214cc1-06d1-45fe-9700-
> dca5726ad7bf
> +  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
> +  PrintLib
> +  FdtLib
> +
> +[Sources.common]
> +  Virt.c
> +  VirtMem.c
> +
> +[Sources.AARCH64]
> +  AARCH64/VirtHelper.S      | GCC
> +
> +[Sources.ARM]
> +  ARM/VirtHelper.S          | GCC
> +
> +[FeaturePcd]
> +  gEmbeddedTokenSpaceGuid.PcdCacheEnable
> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdSystemMemorySize
> +  gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress
> +
> +[FixedPcd]
> +  gArmPlatformTokenSpaceGuid.PcdCoreCount
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
> +  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
> +  gArmTokenSpaceGuid.PcdArmPrimaryCore
> +  gArmTokenSpaceGuid.PcdFdBaseAddress
> +  gArmTokenSpaceGuid.PcdFdSize
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> new file mode 100644
> index 000000000000..a02712274dd3
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/Virt.c
> @@ -0,0 +1,151 @@
> +/** @file
> +*
> +*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
> +*  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +*
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of
> the BSD License
> +*  which accompanies this distribution.  The full text of the license
> may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS
> OR IMPLIED.
> +*
> +**/
> +
> +#include <Library/IoLib.h>
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <ArmPlatform.h>
> +#include <libfdt.h>
> +
> +/**
> +  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
> +  )
> +{
> +  //
> +  // We are relying on ArmPlatformInitializeSystemMemory () being
> called from
> +  // InitializeMemory (), which only occurs if the following feature
> is disabled
> +  //
> +  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Initialize the system (or sometimes called permanent) memory
> +
> +  This memory is generally represented by the DRAM.
> +
> +**/
> +VOID
> +ArmPlatformInitializeSystemMemory (
> +  VOID
> +  )
> +{
> +  VOID    *DeviceTreeBase;
> +  INT32   Node, Prev;
> +  UINT64  NewBase;
> +  UINT64  NewSize;
> +
> +  NewBase = 0;
> +  NewSize = 0;
> +
> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
> +  ASSERT (DeviceTreeBase != NULL);
> +
> +  //
> +  // Make sure we have a valid device tree blob
> +  //
> +  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
> +
> +  //
> +  // Look for a memory node
> +  //
> +  for (Prev = 0;; Prev = Node) {
> +    CONST CHAR8  *Type;
> +    INT32         Len;
> +
> +    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
> +    if (Node < 0) {
> +      break;
> +    }
> +
> +    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
> +    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
> +      CONST UINT64 *RegProp;
> +
> +      //
> +      // Get the 'reg' property of this node. For now, we will assume
> +      // two 8 byte quantities for base and size, respectively.
> +      //
> +      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
> +      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
> +
> +        NewBase = fdt64_to_cpu (RegProp[0]);
> +        NewSize = fdt64_to_cpu (RegProp[1]);
> +
> +        //
> +        // Make sure the start of DRAM matches our expectation
> +        //
> +        ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
> +        PcdSet64 (PcdSystemMemorySize, NewSize);
> +
> +        DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
> +               __FUNCTION__, NewBase, NewBase + NewSize - 1));
> +      } else {
> +        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
> +               __FUNCTION__));
> +      }
> +      break;
> +    }
> +  }
> +  //
> +  // We need to make sure that the machine we are running on has at
> least
> +  // 128 MB of memory configured, and is currently executing this
> binary from
> +  // NOR flash. This prevents a device tree image in DRAM from getting
> +  // clobbered when our caller installs permanent PEI RAM, before we
> have a
> +  // chance of marking its location as reserved or copy it to a
> freshly
> +  // allocated block in the permanent PEI RAM in the platform PEIM.
> +  //
> +  ASSERT (NewSize >= SIZE_128MB);
> +  ASSERT (
> +    (UINT64)PcdGet32 (PcdFdBaseAddress) +
> +     (UINT64)PcdGet32 (PcdFdSize) <= NewBase ||
> +    (UINT64)PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize);
> +}
> +
> +VOID
> +ArmPlatformGetPlatformPpiList (
> +  OUT UINTN                   *PpiListSize,
> +  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
> +  )
> +{
> +  *PpiListSize = 0;
> +  *PpiList = NULL;
> +}
> diff --git
> a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/VirtMem.c
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/VirtMem.c
> new file mode 100644
> index 000000000000..153c1d20e908
> --- /dev/null
> +++
> b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatform
> Lib/VirtMem.c
> @@ -0,0 +1,107 @@
> +/** @file
> +*
> +*  Copyright (c) 2014, Linaro Limited. All rights reserved.
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of
> the BSD License
> +*  which accompanies this distribution.  The full text of the license
> may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS
> OR IMPLIED.
> +*
> +**/
> +
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/ArmPlatformGlobalVariableLib.h>
> +#include <ArmPlatform.h>
> +
> +// Number of Virtual Memory Map Descriptors
> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          4
> +
> +// DDR attributes
> +#define DDR_ATTRIBUTES_CACHED
> ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
> +#define DDR_ATTRIBUTES_UNCACHED
> ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
> +
> +EFI_PHYSICAL_ADDRESS
> +ArmGetPhysAddrTop (
> +  VOID
> +  );
> +
> +/**
> +  Return the Virtual Memory Map of your platform
> +
> +  This Virtual Memory Map is used by MemoryInitPei Module to
> initialize the MMU
> +  on your platform.
> +
> +  @param[out]   VirtualMemoryMap    Array of
> ARM_MEMORY_REGION_DESCRIPTOR
> +                                    describing a Physical-to-Virtual
> Memory
> +                                    mapping. This array must be ended
> by a
> +                                    zero-filled entry
> +
> +**/
> +VOID
> +ArmPlatformGetVirtualMemoryMap (
> +  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
> +  )
> +{
> +  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
> +  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
> +
> +  ASSERT (VirtualMemoryMap != NULL);
> +
> +  VirtualMemoryTable = AllocatePages (
> +                         EFI_SIZE_TO_PAGES (
> +                           sizeof (ARM_MEMORY_REGION_DESCRIPTOR)
> +                           * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
> +                           )
> +                         );
> +
> +  if (VirtualMemoryTable == NULL) {
> +    DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n",
> __FUNCTION__));
> +    return;
> +  }
> +
> +  if (FeaturePcdGet (PcdCacheEnable) == TRUE) {
> +      CacheAttributes = DDR_ATTRIBUTES_CACHED;
> +  } else {
> +      CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
> +  }
> +
> +  // System DRAM
> +  VirtualMemoryTable[0].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
> +  VirtualMemoryTable[0].VirtualBase  =
> VirtualMemoryTable[0].PhysicalBase;
> +  VirtualMemoryTable[0].Length       = PcdGet64 (PcdSystemMemorySize);
> +  VirtualMemoryTable[0].Attributes   = CacheAttributes;
> +
> +  DEBUG ((EFI_D_INFO, "%a: Dumping System DRAM Memory Map:\n"
> +      "\tPhysicalBase: 0x%lX\n"
> +      "\tVirtualBase: 0x%lX\n"
> +      "\tLength: 0x%lX\n",
> +      __FUNCTION__,
> +      VirtualMemoryTable[0].PhysicalBase,
> +      VirtualMemoryTable[0].VirtualBase,
> +      VirtualMemoryTable[0].Length));
> +
> +  // Peripheral space before DRAM
> +  VirtualMemoryTable[1].PhysicalBase = 0x0;
> +  VirtualMemoryTable[1].VirtualBase  = 0x0;
> +  VirtualMemoryTable[1].Length       =
> VirtualMemoryTable[0].PhysicalBase;
> +  VirtualMemoryTable[1].Attributes   =
> ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  // Peripheral space after DRAM
> +  VirtualMemoryTable[2].PhysicalBase = VirtualMemoryTable[0].Length +
> VirtualMemoryTable[1].Length;
> +  VirtualMemoryTable[2].VirtualBase  =
> VirtualMemoryTable[2].PhysicalBase;
> +  VirtualMemoryTable[2].Length       = ArmGetPhysAddrTop () -
> VirtualMemoryTable[2].PhysicalBase;
> +  VirtualMemoryTable[2].Attributes   =
> ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  // End of Table
> +  ZeroMem (&VirtualMemoryTable[3], sizeof
> (ARM_MEMORY_REGION_DESCRIPTOR));
> +
> +  *VirtualMemoryMap = VirtualMemoryTable;
> +}
> --
> 1.8.3.2
> 





------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
diff mbox

Patch

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S
new file mode 100644
index 000000000000..fd0bfe4afa2d
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/AARCH64/VirtHelper.S
@@ -0,0 +1,86 @@ 
+#
+#  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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
+GCC_ASM_EXPORT(ArmGetPhysAddrTop)
+
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
+
+ASM_PFX(ArmPlatformPeiBootAction):
+  ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
+  ldrh   w0, [x0]
+  ret
+
+# IN None
+# OUT x0 = number of cores present in the system
+ASM_PFX(ArmGetCpuCountPerCluster):
+  mov   x0, #1
+  ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+  mov   x0, #1
+  ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_PFX(ArmPlatformGetCorePosition):
+  and   x1, x0, #ARM_CORE_MASK
+  and   x0, x0, #ARM_CLUSTER_MASK
+  add   x0, x1, x0, LSR #6
+  ret
+
+//EFI_PHYSICAL_ADDRESS
+//GetPhysAddrTop (
+//  VOID
+//  );
+ASM_PFX(ArmGetPhysAddrTop):
+  mrs   x0, id_aa64mmfr0_el1
+  adr   x1, .LPARanges
+  and   x0, x0, #7
+  ldrb  w1, [x1, x0]
+  mov   x0, #1
+  lsl   x0, x0, x1
+  ret
+.LPARanges:
+  .byte 32, 36, 40, 42, 44, 48, -1, -1
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S
new file mode 100644
index 000000000000..dc79b982b598
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ARM/VirtHelper.S
@@ -0,0 +1,81 @@ 
+#
+#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+
+#include <AsmMacroIoLib.h>
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
+GCC_ASM_EXPORT(ArmGetPhysAddrTop)
+
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
+
+ASM_PFX(ArmPlatformPeiBootAction):
+  bx    lr
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)
+  ldr    r0, [r0]
+  bx     lr
+
+# IN None
+# OUT r0 = number of cores present in the system
+ASM_PFX(ArmGetCpuCountPerCluster):
+  mov   r0, #1
+  bx    lr
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+  mov   r0, #1
+  bx    lr
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_PFX(ArmPlatformGetCorePosition):
+  and   r1, r0, #ARM_CORE_MASK
+  and   r0, r0, #ARM_CLUSTER_MASK
+  add   r0, r1, r0, LSR #6
+  bx    lr
+
+//EFI_PHYSICAL_ADDRESS
+//GetPhysAddrTop (
+//  VOID
+//  );
+ASM_PFX(ArmGetPhysAddrTop):
+  mov   r0, #0x00000000
+  mov   r1, #0x10000
+  bx    lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
new file mode 100644
index 000000000000..e7d6ec536dcd
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
@@ -0,0 +1,60 @@ 
+#/* @file
+#  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#  Copyright (c) 2014, Linaro Limited. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmVirtualizationPlatformLib
+  FILE_GUID                      = 00214cc1-06d1-45fe-9700-dca5726ad7bf
+  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
+  PrintLib
+  FdtLib
+
+[Sources.common]
+  Virt.c
+  VirtMem.c
+
+[Sources.AARCH64]
+  AARCH64/VirtHelper.S      | GCC
+
+[Sources.ARM]
+  ARM/VirtHelper.S          | GCC
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdDeviceTreeBaseAddress
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
new file mode 100644
index 000000000000..a02712274dd3
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
@@ -0,0 +1,151 @@ 
+/** @file
+*
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+*  Copyright (c) 2014, Linaro Limited. All rights reserved.
+* 
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <ArmPlatform.h>
+#include <libfdt.h>
+
+/**
+  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
+  )
+{
+  //
+  // We are relying on ArmPlatformInitializeSystemMemory () being called from
+  // InitializeMemory (), which only occurs if the following feature is disabled
+  //
+  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
+  return RETURN_SUCCESS;
+}
+
+/**
+  Initialize the system (or sometimes called permanent) memory
+
+  This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+  VOID
+  )
+{
+  VOID    *DeviceTreeBase;
+  INT32   Node, Prev;
+  UINT64  NewBase;
+  UINT64  NewSize;
+
+  NewBase = 0;
+  NewSize = 0;
+
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
+  ASSERT (DeviceTreeBase != NULL);
+
+  //
+  // Make sure we have a valid device tree blob
+  //
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
+
+  //
+  // Look for a memory node
+  //
+  for (Prev = 0;; Prev = Node) {
+    CONST CHAR8  *Type;
+    INT32         Len;
+
+    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+    if (Node < 0) {
+      break;
+    }
+
+    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
+    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
+      CONST UINT64 *RegProp;
+
+      //
+      // Get the 'reg' property of this node. For now, we will assume
+      // two 8 byte quantities for base and size, respectively.
+      //
+      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
+      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
+
+        NewBase = fdt64_to_cpu (RegProp[0]);
+        NewSize = fdt64_to_cpu (RegProp[1]);
+
+        //
+        // Make sure the start of DRAM matches our expectation
+        //
+        ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
+        PcdSet64 (PcdSystemMemorySize, NewSize);
+
+        DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
+               __FUNCTION__, NewBase, NewBase + NewSize - 1));
+      } else {
+        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
+               __FUNCTION__));
+      }
+      break;
+    }
+  }
+  //
+  // We need to make sure that the machine we are running on has at least
+  // 128 MB of memory configured, and is currently executing this binary from
+  // NOR flash. This prevents a device tree image in DRAM from getting
+  // clobbered when our caller installs permanent PEI RAM, before we have a
+  // chance of marking its location as reserved or copy it to a freshly
+  // allocated block in the permanent PEI RAM in the platform PEIM.
+  //
+  ASSERT (NewSize >= SIZE_128MB);
+  ASSERT (
+    (UINT64)PcdGet32 (PcdFdBaseAddress) +
+     (UINT64)PcdGet32 (PcdFdSize) <= NewBase ||
+    (UINT64)PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize);
+}
+
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                   *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
+  )
+{
+  *PpiListSize = 0;
+  *PpiList = NULL;
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c
new file mode 100644
index 000000000000..153c1d20e908
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/VirtMem.c
@@ -0,0 +1,107 @@ 
+/** @file
+*
+*  Copyright (c) 2014, Linaro Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ArmPlatformGlobalVariableLib.h>
+#include <ArmPlatform.h>
+
+// Number of Virtual Memory Map Descriptors
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          4
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED    ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED  ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+EFI_PHYSICAL_ADDRESS
+ArmGetPhysAddrTop (
+  VOID
+  );
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
+  on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR 
+                                    describing a Physical-to-Virtual Memory
+                                    mapping. This array must be ended by a
+                                    zero-filled entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = AllocatePages (
+                         EFI_SIZE_TO_PAGES (
+                           sizeof (ARM_MEMORY_REGION_DESCRIPTOR)
+                           * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS
+                           )
+                         );
+
+  if (VirtualMemoryTable == NULL) {
+    DEBUG ((EFI_D_ERROR, "%a: Error: Failed AllocatePages()\n", __FUNCTION__));
+    return;
+  }
+
+  if (FeaturePcdGet (PcdCacheEnable) == TRUE) {
+      CacheAttributes = DDR_ATTRIBUTES_CACHED;
+  } else {
+      CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+  }
+
+  // System DRAM
+  VirtualMemoryTable[0].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[0].VirtualBase  = VirtualMemoryTable[0].PhysicalBase;
+  VirtualMemoryTable[0].Length       = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[0].Attributes   = CacheAttributes;
+
+  DEBUG ((EFI_D_INFO, "%a: Dumping System DRAM Memory Map:\n"
+      "\tPhysicalBase: 0x%lX\n"
+      "\tVirtualBase: 0x%lX\n"
+      "\tLength: 0x%lX\n",
+      __FUNCTION__,
+      VirtualMemoryTable[0].PhysicalBase,
+      VirtualMemoryTable[0].VirtualBase,
+      VirtualMemoryTable[0].Length));
+
+  // Peripheral space before DRAM
+  VirtualMemoryTable[1].PhysicalBase = 0x0;
+  VirtualMemoryTable[1].VirtualBase  = 0x0;
+  VirtualMemoryTable[1].Length       = VirtualMemoryTable[0].PhysicalBase;
+  VirtualMemoryTable[1].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // Peripheral space after DRAM
+  VirtualMemoryTable[2].PhysicalBase = VirtualMemoryTable[0].Length + VirtualMemoryTable[1].Length;
+  VirtualMemoryTable[2].VirtualBase  = VirtualMemoryTable[2].PhysicalBase;
+  VirtualMemoryTable[2].Length       = ArmGetPhysAddrTop () - VirtualMemoryTable[2].PhysicalBase;
+  VirtualMemoryTable[2].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // End of Table
+  ZeroMem (&VirtualMemoryTable[3], sizeof (ARM_MEMORY_REGION_DESCRIPTOR));
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}