hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
new file mode 100644
index 0000000..723604d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
@@ -0,0 +1,282 @@
+/** @file

+*

+*  Copyright (c) 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 "CpuDxe.h"

+

+/**

+  Searches memory descriptors covered by given memory range.

+

+  This function searches into the Gcd Memory Space for descriptors

+  (from StartIndex to EndIndex) that contains the memory range

+  specified by BaseAddress and Length.

+

+  @param  MemorySpaceMap       Gcd Memory Space Map as array.

+  @param  NumberOfDescriptors  Number of descriptors in map.

+  @param  BaseAddress          BaseAddress for the requested range.

+  @param  Length               Length for the requested range.

+  @param  StartIndex           Start index into the Gcd Memory Space Map.

+  @param  EndIndex             End index into the Gcd Memory Space Map.

+

+  @retval EFI_SUCCESS          Search successfully.

+  @retval EFI_NOT_FOUND        The requested descriptors does not exist.

+

+**/

+EFI_STATUS

+SearchGcdMemorySpaces (

+  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap,

+  IN UINTN                               NumberOfDescriptors,

+  IN EFI_PHYSICAL_ADDRESS                BaseAddress,

+  IN UINT64                              Length,

+  OUT UINTN                             *StartIndex,

+  OUT UINTN                             *EndIndex

+  )

+{

+  UINTN           Index;

+

+  *StartIndex = 0;

+  *EndIndex   = 0;

+  for (Index = 0; Index < NumberOfDescriptors; Index++) {

+    if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&

+        (BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {

+      *StartIndex = Index;

+    }

+    if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) &&

+        ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {

+      *EndIndex = Index;

+      return EFI_SUCCESS;

+    }

+  }

+  return EFI_NOT_FOUND;

+}

+

+

+/**

+  Sets the attributes for a specified range in Gcd Memory Space Map.

+

+  This function sets the attributes for a specified range in

+  Gcd Memory Space Map.

+

+  @param  MemorySpaceMap       Gcd Memory Space Map as array

+  @param  NumberOfDescriptors  Number of descriptors in map

+  @param  BaseAddress          BaseAddress for the range

+  @param  Length               Length for the range

+  @param  Attributes           Attributes to set

+

+  @retval EFI_SUCCESS          Memory attributes set successfully

+  @retval EFI_NOT_FOUND        The specified range does not exist in Gcd Memory Space

+

+**/

+EFI_STATUS

+SetGcdMemorySpaceAttributes (

+  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap,

+  IN UINTN                               NumberOfDescriptors,

+  IN EFI_PHYSICAL_ADDRESS                BaseAddress,

+  IN UINT64                              Length,

+  IN UINT64                              Attributes

+  )

+{

+  EFI_STATUS            Status;

+  UINTN                 Index;

+  UINTN                 StartIndex;

+  UINTN                 EndIndex;

+  EFI_PHYSICAL_ADDRESS  RegionStart;

+  UINT64                RegionLength;

+

+  DEBUG ((DEBUG_GCD, "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",

+      BaseAddress, BaseAddress + Length, Attributes));

+

+  // We do not support a smaller granularity than 4KB on ARM Architecture

+  if ((Length & EFI_PAGE_MASK) != 0) {

+    DEBUG ((DEBUG_WARN,

+            "Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",

+            Length));

+  }

+

+  //

+  // Get all memory descriptors covered by the memory range

+  //

+  Status = SearchGcdMemorySpaces (

+             MemorySpaceMap,

+             NumberOfDescriptors,

+             BaseAddress,

+             Length,

+             &StartIndex,

+             &EndIndex

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Go through all related descriptors and set attributes accordingly

+  //

+  for (Index = StartIndex; Index <= EndIndex; Index++) {

+    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {

+      continue;

+    }

+    //

+    // Calculate the start and end address of the overlapping range

+    //

+    if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {

+      RegionStart = BaseAddress;

+    } else {

+      RegionStart = MemorySpaceMap[Index].BaseAddress;

+    }

+    if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) {

+      RegionLength = BaseAddress + Length - RegionStart;

+    } else {

+      RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;

+    }

+    //

+    // Set memory attributes according to MTRR attribute and the original attribute of descriptor

+    //

+    gDS->SetMemorySpaceAttributes (

+           RegionStart,

+           RegionLength,

+           (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)

+           );

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function modifies the attributes for the memory region specified by BaseAddress and

+  Length from their current attributes to the attributes specified by Attributes.

+

+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  BaseAddress      The physical address that is the start address of a memory region.

+  @param  Length           The size in bytes of the memory region.

+  @param  Attributes       The bit mask of attributes to set for the memory region.

+

+  @retval EFI_SUCCESS           The attributes were set for the memory region.

+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by

+                                BaseAddress and Length cannot be modified.

+  @retval EFI_INVALID_PARAMETER Length is zero.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of

+                                the memory resource range.

+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory

+                                resource range specified by BaseAddress and Length.

+                                The bit mask of attributes is not support for the memory resource

+                                range specified by BaseAddress and Length.

+

+**/

+EFI_STATUS

+EFIAPI

+CpuSetMemoryAttributes (

+  IN EFI_CPU_ARCH_PROTOCOL    *This,

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    EfiAttributes

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       ArmAttributes;

+  UINTN       RegionBaseAddress;

+  UINTN       RegionLength;

+  UINTN       RegionArmAttributes;

+

+  if ((BaseAddress & (SIZE_4KB - 1)) != 0) {

+    // Minimum granularity is SIZE_4KB (4KB on ARM)

+    DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum ganularity is SIZE_4KB\n", BaseAddress, Length, EfiAttributes));

+    return EFI_UNSUPPORTED;

+  }

+

+  // Convert the 'Attribute' into ARM Attribute

+  ArmAttributes = EfiAttributeToArmAttribute (EfiAttributes);

+

+  // Get the region starting from 'BaseAddress' and its 'Attribute'

+  RegionBaseAddress = BaseAddress;

+  Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes);

+

+  // Data & Instruction Caches are flushed when we set new memory attributes.

+  // So, we only set the attributes if the new region is different.

+  if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||

+      ((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))

+  {

+    return SetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0);

+  } else {

+    return EFI_SUCCESS;

+  }

+}

+

+EFI_STATUS

+EFIAPI

+CpuConvertPagesToUncachedVirtualAddress (

+  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL  *This,

+  IN  EFI_PHYSICAL_ADDRESS              Address,

+  IN  UINTN                             Length,

+  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,

+  OUT UINT64                           *Attributes     OPTIONAL

+  )

+{

+  EFI_STATUS                      Status;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;

+

+  if (Attributes != NULL) {

+    Status = gDS->GetMemorySpaceDescriptor (Address, &GcdDescriptor);

+    if (!EFI_ERROR (Status)) {

+      *Attributes = GcdDescriptor.Attributes;

+    }

+  }

+

+  //

+  // Make this address range page fault if accessed. If it is a DMA buffer than this would

+  // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask

+  // to that address.

+  //

+  Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);

+  if (!EFI_ERROR (Status)) {

+    Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);

+  }

+

+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuConvertPagesToUncachedVirtualAddress()\n    Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));

+

+  return Status;

+}

+

+

+EFI_STATUS

+EFIAPI

+CpuReconvertPages (

+  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL  *This,

+  IN  EFI_PHYSICAL_ADDRESS              Address,

+  IN  UINTN                             Length,

+  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,

+  IN  UINT64                            Attributes

+  )

+{

+  EFI_STATUS      Status;

+

+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));

+

+  //

+  // Unmap the aliased Address

+  //

+  Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);

+  if (!EFI_ERROR (Status)) {

+    //

+    // Restore atttributes

+    //

+    Status = SetMemoryAttributes (Address, Length, Attributes, 0);

+  }

+

+  return Status;

+}

+

+

+VIRTUAL_UNCACHED_PAGES_PROTOCOL  gVirtualUncachedPages = {

+  CpuConvertPagesToUncachedVirtualAddress,

+  CpuReconvertPages

+};