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/Application/LinuxLoader/LinuxAtagLoader.c b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.c
new file mode 100644
index 0000000..50a4b47
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.c
@@ -0,0 +1,103 @@
+/** @file

+*

+*  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.

+*

+**/

+

+#include "LinuxInternal.h"

+

+#include <Library/PrintLib.h>

+#include <Library/UefiApplicationEntryPoint.h>

+

+/**

+  The user Entry Point for Application. The user code starts with this function

+  as the real entry point for the application.

+

+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.

+  @param[in] SystemTable    A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS       The entry point is executed successfully.

+  @retval other             Some error occurs when executing this entry point.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                   Status;

+  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage;

+  LINUX_LOADER_OPTIONAL_DATA*  LinuxOptionalData;

+  EFI_DEVICE_PATH*             DevicePathKernel;

+  EFI_DEVICE_PATH*             InitrdDevicePath;

+  CHAR16*                      OptionalDataInitrd;

+  CHAR8*                       OptionalDataArguments;

+  CHAR16*                      Initrd;

+

+  Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);

+  ASSERT_EFI_ERROR (Status);

+

+  if (LoadedImage->LoadOptionsSize == 0) {

+    Status = LinuxLoaderConfig (LoadedImage);

+  } else {

+    // Ensure the signature is correct

+    LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)LoadedImage->LoadOptions;

+    if (LinuxOptionalData->Signature != LINUX_LOADER_SIGNATURE) {

+      return EFI_UNSUPPORTED;

+    }

+

+    // Generate the File Path Node for the Linux Kernel

+    DevicePathKernel = FileDevicePath (LoadedImage->DeviceHandle, LINUX_KERNEL_NAME);

+

+    if (LinuxOptionalData->CmdLineLength > 0) {

+      OptionalDataArguments = (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);

+    } else {

+      OptionalDataArguments = NULL;

+    }

+

+    if (LinuxOptionalData->InitrdPathListLength > 0) {

+      if (OptionalDataArguments != NULL) {

+        OptionalDataInitrd = (CHAR16*)(OptionalDataArguments + LinuxOptionalData->CmdLineLength);

+      } else {

+        OptionalDataInitrd = (CHAR16*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);

+      }

+

+      // If pointer not aligned

+      if ((UINTN)OptionalDataInitrd & 0x1) {

+        Initrd = (CHAR16*)AllocateCopyPool (LinuxOptionalData->InitrdPathListLength, OptionalDataInitrd);

+      } else {

+        Initrd = OptionalDataInitrd;

+      }

+

+      InitrdDevicePath = FileDevicePath (LoadedImage->DeviceHandle, Initrd);

+    } else {

+      OptionalDataInitrd = NULL;

+      InitrdDevicePath   = NULL;

+      Initrd             = NULL;

+    }

+

+    // Load and Start the Linux Kernel (we should never return)

+    Status = BdsBootLinuxAtag (DevicePathKernel, InitrdDevicePath, OptionalDataArguments);

+

+    if ((UINTN)OptionalDataInitrd & 0x1) {

+      FreePool (Initrd);

+    }

+

+    FreePool (DevicePathKernel);

+    if (InitrdDevicePath) {

+      FreePool (InitrdDevicePath);

+    }

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf
new file mode 100644
index 0000000..dcc2597
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf
@@ -0,0 +1,39 @@
+#/* @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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010006

+  BASE_NAME                      = LinuxAtagLoader

+  FILE_GUID                      = a912f198-7f0e-4803-b908-b757b806ec83

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 0.1

+  ENTRY_POINT                    = UefiMain

+

+[Sources]

+  LinuxAtagLoader.c

+  LinuxConfig.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BdsLib

+  DxeServicesTableLib

+  UefiLib

+  UefiApplicationEntryPoint

+

+[Protocols]

+  gEfiLoadedImageProtocolGuid

+  gEfiDevicePathToTextProtocolGuid

+

diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxConfig.c b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxConfig.c
new file mode 100644
index 0000000..c88dc65
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxConfig.c
@@ -0,0 +1,354 @@
+/** @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 "LinuxInternal.h"

+

+#define DEFAULT_BOOT_ENTRY_DESCRIPTION  L"Linux"

+#define MAX_STR_INPUT                   300

+#define MAX_ASCII_INPUT                 300

+

+typedef enum {

+  LINUX_LOADER_NEW = 1,

+  LINUX_LOADER_UPDATE

+} LINUX_LOADER_ACTION;

+

+STATIC

+EFI_STATUS

+EditHIInputStr (

+  IN OUT CHAR16  *CmdLine,

+  IN     UINTN   MaxCmdLine

+  )

+{

+  UINTN           CmdLineIndex;

+  UINTN           WaitIndex;

+  CHAR8           Char;

+  EFI_INPUT_KEY   Key;

+  EFI_STATUS      Status;

+

+  Print (CmdLine);

+

+  for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {

+    Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);

+    ASSERT_EFI_ERROR (Status);

+

+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+    ASSERT_EFI_ERROR (Status);

+

+    // Unicode character is valid when Scancode is NUll

+    if (Key.ScanCode == SCAN_NULL) {

+      // Scan code is NUll, hence read Unicode character

+      Char = (CHAR8)Key.UnicodeChar;

+    } else {

+      Char = CHAR_NULL;

+    }

+

+    if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {

+      CmdLine[CmdLineIndex] = '\0';

+      Print (L"\n\r");

+

+      return EFI_SUCCESS;

+    } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){

+      if (CmdLineIndex != 0) {

+        CmdLineIndex--;

+        Print (L"\b \b");

+      }

+    } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {

+      return EFI_INVALID_PARAMETER;

+    } else {

+      CmdLine[CmdLineIndex++] = Key.UnicodeChar;

+      Print (L"%c", Key.UnicodeChar);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+EditHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  )

+{

+  CHAR16*     Str;

+  EFI_STATUS  Status;

+

+  Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));

+  AsciiStrToUnicodeStr (CmdLine, Str);

+

+  Status = EditHIInputStr (Str, MaxCmdLine);

+

+  UnicodeStrToAsciiStr (Str, CmdLine);

+  FreePool (Str);

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+GetHIInputInteger (

+  OUT UINTN   *Integer

+  )

+{

+  CHAR16      CmdLine[255];

+  EFI_STATUS  Status;

+

+  CmdLine[0] = '\0';

+  Status = EditHIInputStr (CmdLine, 255);

+  if (!EFI_ERROR(Status)) {

+    *Integer = StrDecimalToUintn (CmdLine);

+  }

+

+  return Status;

+}

+

+#if 0

+EFI_STATUS

+GenerateDeviceDescriptionName (

+  IN  EFI_HANDLE  Handle,

+  IN OUT CHAR16*  Description

+  )

+{

+  EFI_STATUS                        Status;

+  EFI_COMPONENT_NAME_PROTOCOL*      ComponentName2Protocol;

+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

+  CHAR16*                           DriverName;

+  CHAR16*                           DevicePathTxt;

+  EFI_DEVICE_PATH*                  DevicePathNode;

+

+  ComponentName2Protocol = NULL;

+  Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);

+  if (!EFI_ERROR(Status)) {

+    //TODO: Fixme. we must find the best langague

+    Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);

+    if (!EFI_ERROR(Status)) {

+      StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX);

+    }

+  }

+

+  if (EFI_ERROR(Status)) {

+    // Use the lastest non null entry of the Device path as a description

+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);

+    if (EFI_ERROR(Status)) {

+      return Status;

+    }

+

+    // Convert the last non end-type Device Path Node in text for the description

+    DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);

+    Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+    ASSERT_EFI_ERROR(Status);

+    DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE);

+    StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);

+    FreePool (DevicePathTxt);

+  }

+

+  return EFI_SUCCESS;

+}

+#endif

+

+EFI_STATUS

+LinuxLoaderConfig (

+  IN EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage

+  )

+{

+  EFI_STATUS                   Status;

+  LINUX_LOADER_ACTION          Choice;

+  UINTN                        BootOrderSize;

+  UINT16*                      BootOrder;

+  UINTN                        BootOrderCount;

+  UINTN                        Index;

+  CHAR16                       Description[MAX_ASCII_INPUT];

+  CHAR8                        CmdLine[MAX_ASCII_INPUT];

+  CHAR16                       Initrd[MAX_STR_INPUT];

+  UINT16                       InitrdPathListLength;

+  UINT16                       CmdLineLength;

+  BDS_LOAD_OPTION*             BdsLoadOption;

+  BDS_LOAD_OPTION**            SupportedBdsLoadOptions;

+  UINTN                        SupportedBdsLoadOptionCount;

+  LINUX_LOADER_OPTIONAL_DATA*  LinuxOptionalData;

+  EFI_DEVICE_PATH*             DevicePathRoot;

+

+  Choice = (LINUX_LOADER_ACTION)0;

+  SupportedBdsLoadOptions = NULL;

+  SupportedBdsLoadOptionCount = 0;

+

+  do {

+    Print (L"[%d] Create new Linux Boot Entry\n",LINUX_LOADER_NEW);

+    Print (L"[%d] Update Linux Boot Entry\n",LINUX_LOADER_UPDATE);

+

+    Print (L"Option: ");

+    Status = GetHIInputInteger ((UINTN*)&Choice);

+    if (Status == EFI_INVALID_PARAMETER) {

+      Print (L"\n");

+      return Status;

+    } else if ((Choice != LINUX_LOADER_NEW) && (Choice != LINUX_LOADER_UPDATE)) {

+      Print (L"Error: the option should be either '%d' or '%d'\n",LINUX_LOADER_NEW,LINUX_LOADER_UPDATE);

+      Status = EFI_INVALID_PARAMETER;

+    }

+  } while (EFI_ERROR(Status));

+

+  if (Choice == LINUX_LOADER_UPDATE) {

+    // If no compatible entry then we just create a new entry

+    Choice = LINUX_LOADER_NEW;

+

+    // Scan the OptionalData of every entry for the correct signature

+    Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+    if (!EFI_ERROR(Status)) {

+      BootOrderCount = BootOrderSize / sizeof(UINT16);

+

+      // Allocate an array to handle maximum number of supported Boot Entry

+      SupportedBdsLoadOptions = (BDS_LOAD_OPTION**)AllocatePool(sizeof(BDS_LOAD_OPTION*) * BootOrderCount);

+

+      SupportedBdsLoadOptionCount = 0;

+

+      // Check if the signature is present in the list of the current Boot entries

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

+        Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);

+        if (!EFI_ERROR(Status)) {

+          if ((BdsLoadOption->OptionalDataSize >= sizeof(UINT32)) &&

+              (*(UINT32*)BdsLoadOption->OptionalData == LINUX_LOADER_SIGNATURE)) {

+            SupportedBdsLoadOptions[SupportedBdsLoadOptionCount++] = BdsLoadOption;

+            Choice = LINUX_LOADER_UPDATE;

+          }

+        }

+      }

+    }

+    FreePool (BootOrder);

+  }

+

+  if (Choice == LINUX_LOADER_NEW) {

+    Description[0] = '\0';

+    CmdLine[0]     = '\0';

+    Initrd[0]      = '\0';

+

+    BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));

+

+    DEBUG_CODE_BEGIN();

+      CHAR16*                           DevicePathTxt;

+      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+

+      Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+      ASSERT_EFI_ERROR(Status);

+      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE);

+

+      Print(L"EFI OS Loader: %s\n",DevicePathTxt);

+

+      FreePool(DevicePathTxt);

+    DEBUG_CODE_END();

+

+    //

+    // Fill the known fields of BdsLoadOption

+    //

+

+    BdsLoadOption->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT;

+

+    // Get the full Device Path for this file

+    Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathRoot);

+    ASSERT_EFI_ERROR(Status);

+

+    BdsLoadOption->FilePathList = AppendDevicePath (DevicePathRoot, LoadedImage->FilePath);

+    BdsLoadOption->FilePathListLength = GetDevicePathSize (BdsLoadOption->FilePathList);

+  } else {

+    if (SupportedBdsLoadOptionCount > 1) {

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

+        Print (L"[%d] %s\n",Index + 1,SupportedBdsLoadOptions[Index]->Description);

+      }

+

+      do {

+        Print (L"Update Boot Entry: ");

+        Status = GetHIInputInteger ((UINTN*)&Choice);

+        if (Status == EFI_INVALID_PARAMETER) {

+          Print (L"\n");

+          return Status;

+        } else if ((Choice < 1) && (Choice > SupportedBdsLoadOptionCount)) {

+          Print (L"Choose entry from 1 to %d\n",SupportedBdsLoadOptionCount);

+          Status = EFI_INVALID_PARAMETER;

+        }

+      } while (EFI_ERROR(Status));

+      BdsLoadOption = SupportedBdsLoadOptions[Choice-1];

+    }

+    StrnCpy (Description, BdsLoadOption->Description, MAX_STR_INPUT);

+

+    LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)BdsLoadOption->OptionalData;

+    if (LinuxOptionalData->CmdLineLength > 0) {

+      CopyMem (CmdLine, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA), LinuxOptionalData->CmdLineLength);

+    } else {

+      CmdLine[0] = '\0';

+    }

+

+    if (LinuxOptionalData->InitrdPathListLength > 0) {

+      CopyMem (Initrd, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA) + LinuxOptionalData->CmdLineLength, LinuxOptionalData->InitrdPathListLength);

+    } else {

+      Initrd[0] = L'\0';

+    }

+    DEBUG((EFI_D_ERROR,"L\n"));

+  }

+

+  // Description

+  Print (L"Description: ");

+  Status = EditHIInputStr (Description, MAX_STR_INPUT);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+  if (StrLen (Description) == 0) {

+    StrnCpy (Description, DEFAULT_BOOT_ENTRY_DESCRIPTION, MAX_STR_INPUT);

+  }

+  BdsLoadOption->Description = Description;

+

+  // CmdLine

+  Print (L"Command Line: ");

+  Status = EditHIInputAscii (CmdLine, MAX_ASCII_INPUT);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  // Initrd

+  Print (L"Initrd name: ");

+  Status = EditHIInputStr (Initrd, MAX_STR_INPUT);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  CmdLineLength = AsciiStrLen (CmdLine);

+  if (CmdLineLength > 0) {

+    CmdLineLength += sizeof(CHAR8);

+  }

+

+  InitrdPathListLength = StrLen (Initrd) * sizeof(CHAR16);

+  if (InitrdPathListLength > 0) {

+    InitrdPathListLength += sizeof(CHAR16);

+  }

+

+  BdsLoadOption->OptionalDataSize = sizeof(LINUX_LOADER_OPTIONAL_DATA) + CmdLineLength + InitrdPathListLength;

+

+  LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)AllocatePool (BdsLoadOption->OptionalDataSize);

+  BdsLoadOption->OptionalData = LinuxOptionalData;

+

+  LinuxOptionalData->Signature = LINUX_LOADER_SIGNATURE;

+  LinuxOptionalData->CmdLineLength = CmdLineLength;

+  LinuxOptionalData->InitrdPathListLength = InitrdPathListLength;

+

+  if (CmdLineLength > 0) {

+    CopyMem (LinuxOptionalData + 1, CmdLine, CmdLineLength);

+  }

+  if (InitrdPathListLength > 0) {

+    CopyMem ((UINT8*)(LinuxOptionalData + 1) + CmdLineLength, Initrd, InitrdPathListLength);

+  }

+

+  // Create or Update the boot entry

+  Status = BootOptionToLoadOptionVariable (BdsLoadOption);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c
new file mode 100644
index 0000000..07d0ea7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c
@@ -0,0 +1,105 @@
+/** @file

+*

+*  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.

+*

+**/

+

+#include "LinuxInternal.h"

+

+#include <Library/PrintLib.h>

+#include <Library/UefiApplicationEntryPoint.h>

+

+/**

+  The user Entry Point for Application. The user code starts with this function

+  as the real entry point for the application.

+

+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.

+  @param[in] SystemTable    A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS       The entry point is executed successfully.

+  @retval other             Some error occurs when executing this entry point.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                   Status;

+  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage;

+  LINUX_LOADER_OPTIONAL_DATA*  LinuxOptionalData;

+  EFI_DEVICE_PATH*             DevicePathKernel;

+  EFI_DEVICE_PATH*             DevicePathFdt;

+  EFI_DEVICE_PATH*             InitrdDevicePath;

+  CHAR16*                      OptionalDataInitrd;

+  CHAR8*                       OptionalDataArguments;

+  CHAR16*                      Initrd;

+

+  Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);

+  ASSERT_EFI_ERROR (Status);

+

+  if (LoadedImage->LoadOptionsSize == 0) {

+    Status = LinuxLoaderConfig (LoadedImage);

+  } else {

+    // Ensure the signature is correct

+    LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)LoadedImage->LoadOptions;

+    if (LinuxOptionalData->Signature != LINUX_LOADER_SIGNATURE) {

+      return EFI_UNSUPPORTED;

+    }

+

+    // Generate the File Path Node for the Linux Kernel & Device Tree blob

+    DevicePathKernel = FileDevicePath (LoadedImage->DeviceHandle, LINUX_KERNEL_NAME);

+    DevicePathFdt    = FileDevicePath (LoadedImage->DeviceHandle, FDT_NAME);

+

+    if (LinuxOptionalData->CmdLineLength > 0) {

+      OptionalDataArguments = (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);

+    } else {

+      OptionalDataArguments = NULL;

+    }

+

+    if (LinuxOptionalData->InitrdPathListLength > 0) {

+      if (OptionalDataArguments != NULL) {

+        OptionalDataInitrd = (CHAR16*)(OptionalDataArguments + LinuxOptionalData->CmdLineLength);

+      } else {

+        OptionalDataInitrd = (CHAR16*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);

+      }

+

+      // If pointer not aligned

+      if ((UINTN)OptionalDataInitrd & 0x1) {

+        Initrd = (CHAR16*)AllocateCopyPool (LinuxOptionalData->InitrdPathListLength, OptionalDataInitrd);

+      } else {

+        Initrd = OptionalDataInitrd;

+      }

+

+      InitrdDevicePath = FileDevicePath (LoadedImage->DeviceHandle, Initrd);

+    } else {

+      OptionalDataInitrd = NULL;

+      InitrdDevicePath   = NULL;

+      Initrd             = NULL;

+    }

+

+    // Load and Start the Linux Kernel (we should never return)

+    Status = BdsBootLinuxFdt (DevicePathKernel, InitrdDevicePath, OptionalDataArguments, DevicePathFdt);

+

+    if ((UINTN)OptionalDataInitrd & 0x1) {

+      FreePool (Initrd);

+    }

+

+    FreePool (DevicePathKernel);

+    if (InitrdDevicePath) {

+      FreePool (InitrdDevicePath);

+    }

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf
new file mode 100644
index 0000000..55a6969
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf
@@ -0,0 +1,39 @@
+#/* @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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010006

+  BASE_NAME                      = LinuxFdtLoader

+  FILE_GUID                      = f536d559-459f-48fa-8bbc-43b554ecae8d

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 0.1

+  ENTRY_POINT                    = UefiMain

+

+[Sources]

+  LinuxFdtLoader.c

+  LinuxConfig.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BdsLib

+  DxeServicesTableLib

+  UefiLib

+  UefiApplicationEntryPoint

+

+[Protocols]

+  gEfiLoadedImageProtocolGuid

+  gEfiDevicePathToTextProtocolGuid

+

diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxInternal.h b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxInternal.h
new file mode 100644
index 0000000..88d786f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxInternal.h
@@ -0,0 +1,50 @@
+/** @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.

+*

+**/

+

+#ifndef __LOADER_INTERNAL_H

+#define __LOADER_INTERNAL_H

+

+#include <Uefi.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BdsLib.h>

+#include <Library/DebugLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+

+#include <Protocol/LoadedImage.h>

+#include <Protocol/DevicePathToText.h>

+

+#define LINUX_KERNEL_NAME               L"zImage"

+#define FDT_NAME                        L"platform.dtb"

+

+#define LINUX_LOADER_SIGNATURE    SIGNATURE_32('l', 'i', 'l', 'o')

+

+typedef struct {

+  UINT32                        Signature;

+  UINT16                        CmdLineLength;

+  UINT16                        InitrdPathListLength;

+

+  // These following fields have variable length:

+  //CHAR8*                      CmdLine;

+  //CHAR16*                     Initrd;

+} LINUX_LOADER_OPTIONAL_DATA;

+

+EFI_STATUS

+LinuxLoaderConfig (

+  IN EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/ArmPkg.dec b/uefi/linaro-edk2/ArmPkg/ArmPkg.dec
new file mode 100644
index 0000000..ced3929
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/ArmPkg.dec
@@ -0,0 +1,249 @@
+#/** @file

+# ARM processor package.

+#

+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#**/

+

+[Defines]

+  DEC_SPECIFICATION              = 0x00010005

+  PACKAGE_NAME                   = ArmPkg

+  PACKAGE_GUID                   = 5CFBD99E-3C43-4E7F-8054-9CDEAFF7710F

+  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

+

+[LibraryClasses.common]

+  ArmLib|Include/Library/ArmLib.h

+  SemihostLib|Include/Library/Semihosting.h

+  UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h

+  DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.h

+  ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h

+

+[Guids.common]

+  gArmTokenSpaceGuid       = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }

+

+  ## ARM MPCore table

+  # Include/Guid/ArmMpCoreInfo.h

+  gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }

+

+[Ppis]

+  ## Include/Ppi/ArmMpCoreInfo.h

+  gArmMpCoreInfoPpiGuid = { 0x6847cc74, 0xe9ec, 0x4f8f, {0xa2, 0x9d, 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc} }

+

+[Protocols.common]

+  gVirtualUncachedPagesProtocolGuid = { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }

+

+[PcdsFeatureFlag.common]

+  gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE|BOOLEAN|0x00000001

+

+  # On ARM Architecture with the Security Extension, the address for the

+  # Vector Table can be mapped anywhere in the memory map. It means we can

+  # point the Exception Vector Table to its location in CpuDxe.

+  # By default we copy the Vector Table at  PcdGet32(PcdCpuVectorBaseAddress)

+  gArmTokenSpaceGuid.PcdRelocateVectorTable|TRUE|BOOLEAN|0x00000022

+  # Set this PCD to TRUE if the Exception Vector is changed to add debugger support before

+  # it has been configured by the CPU DXE

+  gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|FALSE|BOOLEAN|0x00000032

+

+  # Define if the spin-table mechanism is used by the secondary cores when booting

+  # Linux (instead of PSCI)

+  gArmTokenSpaceGuid.PcdArmLinuxSpinTable|FALSE|BOOLEAN|0x00000033

+

+  # Define if the GICv3 controller should use the GICv2 legacy

+  gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042

+

+[PcdsFixedAtBuild.common]

+  gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006

+

+  # This PCD should be a FeaturePcd. But we used this PCD as an '#if' in an ASM file.

+  # Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.

+  gArmTokenSpaceGuid.PcdVFPEnabled|0|UINT32|0x00000024

+

+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000080000000|UINT64|0x00000002

+  # This PCD will free the unallocated buffers if their size reach this threshold.

+  # We set the default value to 512MB.

+  gArmTokenSpaceGuid.PcdArmFreeUncachedMemorySizeThreshold|0x20000000|UINT64|0x00000043

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003

+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xffff0000|UINT32|0x00000004

+  gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005

+

+  #

+  # ARM Secure Firmware PCDs

+  #

+  gArmTokenSpaceGuid.PcdSecureFdBaseAddress|0|UINT64|0x00000015

+  gArmTokenSpaceGuid.PcdSecureFdSize|0|UINT32|0x00000016

+  gArmTokenSpaceGuid.PcdSecureFvBaseAddress|0x0|UINT64|0x0000002F

+  gArmTokenSpaceGuid.PcdSecureFvSize|0x0|UINT32|0x00000030

+

+  #

+  # ARM Normal (or Non Secure) Firmware PCDs

+  #

+  gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B

+  gArmTokenSpaceGuid.PcdFdSize|0|UINT32|0x0000002C

+  gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D

+  gArmTokenSpaceGuid.PcdFvSize|0|UINT32|0x0000002E

+

+  #

+  # ARM Hypervisor Firmware PCDs

+  #

+  gArmTokenSpaceGuid.PcdHypFdBaseAddress|0|UINT32|0x0000003A

+  gArmTokenSpaceGuid.PcdHypFdSize|0|UINT32|0x0000003B

+  gArmTokenSpaceGuid.PcdHypFvBaseAddress|0|UINT32|0x0000003C

+  gArmTokenSpaceGuid.PcdHypFvSize|0|UINT32|0x0000003D

+

+  # Use ClusterId + CoreId to identify the PrimaryCore

+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask|0xF03|UINT32|0x00000031

+  # The Primary Core is ClusterId[0] & CoreId[0]

+  gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037

+

+  #

+  # ARM L2x0 PCDs

+  #

+  gArmTokenSpaceGuid.PcdL2x0ControllerBase|0|UINT32|0x0000001B

+

+  #

+  # BdsLib

+  #

+  gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E

+  # The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory

+  gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F

+  # Maximum file size for TFTP servers that do not support 'tsize' extension

+  gArmTokenSpaceGuid.PcdMaxTftpFileSize|0x01000000|UINT32|0x00000000

+

+

+[PcdsFixedAtBuild.ARM]

+  #

+  # ARM Security Extension

+  #

+

+  # Secure Configuration Register

+  # - BIT0 : NS - Non Secure bit

+  # - BIT1 : IRQ Handler

+  # - BIT2 : FIQ Handler

+  # - BIT3 : EA - External Abort

+  # - BIT4 : FW - F bit writable

+  # - BIT5 : AW - A bit writable

+  # - BIT6 : nET - Not Early Termination

+  # - BIT7 : SCD - Secure Monitor Call Disable

+  # - BIT8 : HCE - Hyp Call enable

+  # - BIT9 : SIF - Secure Instruction Fetch

+  # 0x31 = NS | EA | FW

+  gArmTokenSpaceGuid.PcdArmScr|0x31|UINT32|0x00000038

+

+  # By default we do not do a transition to non-secure mode

+  gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E

+

+  # The Linux ATAGs are expected to be under 0x4000 (16KB) from the beginning of the System Memory

+  gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset|0x4000|UINT32|0x00000020

+

+  # If the fixed FDT address is not available, then it should be loaded below the kernel.

+  # The recommendation from the Linux kernel is to have the FDT below 16KB.

+  # (see the kernel doc: Documentation/arm/Booting)

+  gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x4000|UINT32|0x00000023

+  # The FDT blob must be loaded at a 64bit aligned address.

+  gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x8|UINT32|0x00000026

+

+  # Non Secure Access Control Register

+  # - BIT15 : NSASEDIS - Disable Non-secure Advanced SIMD functionality

+  # - BIT14 : NSD32DIS - Disable Non-secure use of D16-D31

+  # - BIT11 : cp11 - Non-secure access to coprocessor 11 enable

+  # - BIT10 : cp10 - Non-secure access to coprocessor 10 enable

+  # 0xC00 = cp10 | cp11

+  gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039

+

+[PcdsFixedAtBuild.AARCH64]

+  #

+  # AArch64 Security Extension

+  #

+

+  # Secure Configuration Register

+  # - BIT0 : NS - Non Secure bit

+  # - BIT1 : IRQ Handler

+  # - BIT2 : FIQ Handler

+  # - BIT3 : EA - External Abort

+  # - BIT4 : FW - F bit writable

+  # - BIT5 : AW - A bit writable

+  # - BIT6 : nET - Not Early Termination

+  # - BIT7 : SCD - Secure Monitor Call Disable

+  # - BIT8 : HCE - Hyp Call enable

+  # - BIT9 : SIF - Secure Instruction Fetch

+  # - BIT10: RW -  Register width control for lower exception levels

+  # - BIT11: SIF - Enables Secure EL1 access to EL1 Architectural Timer

+  # - BIT12: TWI - Trap WFI

+  # - BIT13: TWE - Trap WFE

+  # 0x501 = NS | HCE | RW

+  gArmTokenSpaceGuid.PcdArmScr|0x501|UINT32|0x00000038

+

+  # By default we do transition to EL2 non-secure mode with Stack for EL2.

+  #        Mode Description              Bits

+  # NS EL2 SP2 all interrupts disabled =  0x3c9

+  # NS EL1 SP1 all interrupts disabled =  0x3c5

+  # Other modes include using SP0 or switching to Aarch32, but these are

+  # not currently supported.

+  gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x3c9|UINT32|0x0000003E

+  # If the fixed FDT address is not available, then it should be loaded above the kernel.

+  # The recommendation from the AArch64 Linux kernel is to have the FDT below 512MB.

+  # (see the kernel doc: Documentation/arm64/booting.txt)

+  gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x20000000|UINT32|0x00000023

+  # The FDT blob must be loaded at a 2MB aligned address.

+  gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x00200000|UINT32|0x00000026

+

+

+#

+# These PCDs are also defined as 'PcdsDynamic' to be redefined when using UEFI in a

+# context of virtual machine.

+#

+[PcdsFixedAtBuild.common, PcdsDynamic.common]

+  # System Memory (DRAM): These PCDs define the region of in-built system memory

+  # Some platforms can get DRAM extensions, these additional regions will be declared

+  # to UEFI by ArmPlatformLib

+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0|UINT64|0x00000029

+  gArmTokenSpaceGuid.PcdSystemMemorySize|0|UINT64|0x0000002A

+

+  #

+  # ARM Architectural Timer

+  #

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0|UINT32|0x00000034

+

+  # ARM Architectural Timer Interrupt(GIC PPI) numbers

+  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035

+  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036

+  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040

+  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041

+

+  #

+  # ARM Generic Watchdog

+  #

+

+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x2A440000|UINT32|0x00000007

+  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x2A450000|UINT32|0x00000008

+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|93|UINT32|0x00000009

+

+  #

+  # ARM Generic Interrupt Controller

+  #

+  gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C

+  # Base address for the GIC Redistributor region that contains the boot CPU

+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0|UINT32|0x0000000E

+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D

+  gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025

diff --git a/uefi/linaro-edk2/ArmPkg/ArmPkg.dsc b/uefi/linaro-edk2/ArmPkg/ArmPkg.dsc
new file mode 100644
index 0000000..be5126c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/ArmPkg.dsc
@@ -0,0 +1,164 @@
+#/** @file

+# ARM processor package.

+#

+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>

+# 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 Section - statements that will be processed to create a Makefile.

+#

+################################################################################

+[Defines]

+  PLATFORM_NAME                  = ArmPkg

+  PLATFORM_GUID                  = 5CFBD99E-3C43-4E7F-8054-9CDEAFF7710F

+  PLATFORM_VERSION               = 0.1

+  DSC_SPECIFICATION              = 0x00010005

+  OUTPUT_DIRECTORY               = Build/Arm

+  SUPPORTED_ARCHITECTURES        = ARM|AARCH64

+  BUILD_TARGETS                  = DEBUG|RELEASE

+  SKUID_IDENTIFIER               = DEFAULT

+

+[BuildOptions]

+  XCODE:*_*_ARM_PLATFORM_FLAGS  == -arch armv7

+  GCC:*_*_ARM_PLATFORM_FLAGS    == -march=armv7-a -mfpu=neon

+  # We use A15 to get the Secure and Virtualization extensions

+  RVCT:*_*_ARM_PLATFORM_FLAGS  == --cpu Cortex-A15

+

+  RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG

+

+[LibraryClasses.common]

+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf

+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf

+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf

+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf

+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf

+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf

+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf

+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf

+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf

+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf

+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf

+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf

+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf

+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf

+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf

+

+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf

+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf

+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf

+

+  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf

+  UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf

+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf

+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf

+

+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf

+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf

+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf

+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf

+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf

+  DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf

+

+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf

+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf

+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf

+

+  BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf

+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf

+

+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf

+

+[LibraryClasses.ARM]

+  ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf

+

+[LibraryClasses.AARCH64]

+  ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf

+

+[LibraryClasses.common.PEIM]

+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf

+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf

+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf

+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf

+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf

+

+[LibraryClasses.common.DXE_DRIVER]

+  ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Dxe/DxeArmPlatformGlobalVariableLib.inf

+

+[LibraryClasses.ARM, LibraryClasses.AARCH64]

+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

+

+  # Add support for GCC stack protector

+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf

+

+[Components.common]

+  ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf

+  ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf

+  ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf

+  ArmPkg/Library/ArmLib/Null/NullArmLib.inf

+  ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf

+  ArmPkg/Library/BdsLib/BdsLib.inf

+  ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

+  ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf

+  ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf

+  ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf

+  ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf

+  ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf

+  ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf

+  ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf

+  ArmPkg/Library/SemihostLib/SemihostLib.inf

+  ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf

+  ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf

+

+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf

+  ArmPkg/Drivers/CpuPei/CpuPei.inf

+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf

+  ArmPkg/Drivers/ArmGic/ArmGicLib.inf

+  ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf

+  ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf

+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf

+

+  ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf

+  ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf

+

+  ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf

+  ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf

+  ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf

+

+  ArmPkg/Filesystem/SemihostFs/SemihostFs.inf

+

+  ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf

+

+[Components.ARM]

+  ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf

+

+  ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf

+  ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf

+  ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf

+

+#  ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf

+#  ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf

+#  ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf

+#  ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf

+  ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf

+  ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf

+

+  ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf

+

+[Components.AARCH64]

+  ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf

+  ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf

+

+  ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf

+  ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf

diff --git a/uefi/linaro-edk2/ArmPkg/Contributions.txt b/uefi/linaro-edk2/ArmPkg/Contributions.txt
new file mode 100644
index 0000000..f87cbd7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Contributions.txt
@@ -0,0 +1,218 @@
+

+======================

+= Code Contributions =

+======================

+

+To make a contribution to a TianoCore project, follow these steps.

+1. Create a change description in the format specified below to

+   use in the source control commit log.

+2. Your commit message must include your "Signed-off-by" signature,

+   and "Contributed-under" message.

+3. Your "Contributed-under" message explicitly states that the

+   contribution is made under the terms of the specified

+   contribution agreement.  Your "Contributed-under" message

+   must include the name of contribution agreement and version.

+   For example: Contributed-under: TianoCore Contribution Agreement 1.0

+   The "TianoCore Contribution Agreement" is included below in

+   this document.

+4. Submit your code to the TianoCore project using the process

+   that the project documents on its web page.  If the process is

+   not documented, then submit the code on development email list

+   for the project.

+5. It is preferred that contributions are submitted using the same

+   copyright license as the base project. When that is not possible,

+   then contributions using the following licenses can be accepted:

+   * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause

+   * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause

+   * MIT: http://opensource.org/licenses/MIT

+   * Python-2.0: http://opensource.org/licenses/Python-2.0

+   * Zlib: http://opensource.org/licenses/Zlib

+

+   Contributions of code put into the public domain can also be

+   accepted.

+

+   Contributions using other licenses might be accepted, but further

+   review will be required.

+

+=====================================================

+= Change Description / Commit Message / Patch Email =

+=====================================================

+

+Your change description should use the standard format for a

+commit message, and must include your "Signed-off-by" signature

+and the "Contributed-under" message.

+

+== Sample Change Description / Commit Message =

+

+=== Start of sample patch email message ===

+

+From: Contributor Name <contributor@example.com>

+Subject: [PATCH] CodeModule: Brief-single-line-summary

+

+Full-commit-message

+

+Contributed-under: TianoCore Contribution Agreement 1.0

+Signed-off-by: Contributor Name <contributor@example.com>

+---

+

+An extra message for the patch email which will not be considered part

+of the commit message can be added here.

+

+Patch content inline or attached

+

+=== End of sample patch email message ===

+

+=== Notes for sample patch email ===

+

+* The first line of commit message is taken from the email's subject

+  line following [PATCH]. The remaining portion of the commit message

+  is the email's content until the '---' line.

+* git format-patch is one way to create this format

+

+=== Definitions for sample patch email ===

+

+* "CodeModule" is a short idenfier for the affected code.  For

+  example MdePkg, or MdeModulePkg UsbBusDxe.

+* "Brief-single-line-summary" is a short summary of the change.

+* The entire first line should be less than ~70 characters.

+* "Full-commit-message" a verbose multiple line comment describing

+  the change.  Each line should be less than ~70 characters.

+* "Contributed-under" explicitely states that the contribution is

+  made under the terms of the contribtion agreement.  This

+  agreement is included below in this document.

+* "Signed-off-by" is the contributor's signature identifying them

+  by their real/legal name and their email address.

+

+========================================

+= TianoCore Contribution Agreement 1.0 =

+========================================

+

+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,

+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE

+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE

+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE

+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR

+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE

+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS

+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED

+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS

+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE

+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT

+USE THE CONTENT.

+

+Unless otherwise indicated, all Content made available on the TianoCore

+site is provided to you under the terms and conditions of the BSD

+License ("BSD"). A copy of the BSD License is available at

+http://opensource.org/licenses/bsd-license.php

+or when applicable, in the associated License.txt file.

+

+Certain other content may be made available under other licenses as

+indicated in or with such Content. (For example, in a License.txt file.)

+

+You accept and agree to the following terms and conditions for Your

+present and future Contributions submitted to TianoCore site. Except

+for the license granted to Intel hereunder, You reserve all right,

+title, and interest in and to Your Contributions.

+

+== SECTION 1: Definitions ==

+* "You" or "Contributor" shall mean the copyright owner or legal

+  entity authorized by the copyright owner that is making a

+  Contribution hereunder. All other entities that control, are

+  controlled by, or are under common control with that entity are

+  considered to be a single Contributor. For the purposes of this

+  definition, "control" means (i) the power, direct or indirect, to

+  cause the direction or management of such entity, whether by

+  contract or otherwise, or (ii) ownership of fifty percent (50%)

+  or more of the outstanding shares, or (iii) beneficial ownership

+  of such entity.

+* "Contribution" shall mean any original work of authorship,

+  including any modifications or additions to an existing work,

+  that is intentionally submitted by You to the TinaoCore site for

+  inclusion in, or documentation of, any of the Content. For the

+  purposes of this definition, "submitted" means any form of

+  electronic, verbal, or written communication sent to the

+  TianoCore site or its representatives, including but not limited

+  to communication on electronic mailing lists, source code

+  control systems, and issue tracking systems that are managed by,

+  or on behalf of, the TianoCore site for the purpose of

+  discussing and improving the Content, but excluding

+  communication that is conspicuously marked or otherwise

+  designated in writing by You as "Not a Contribution."

+

+== SECTION 2: License for Contributions ==

+* Contributor hereby agrees that redistribution and use of the

+  Contribution in source and binary forms, with or without

+  modification, are permitted provided that the following

+  conditions are met:

+** Redistributions of source code must retain the Contributor's

+   copyright notice, this list of conditions and the following

+   disclaimer.

+** Redistributions in binary form must reproduce the Contributor's

+   copyright notice, this list of conditions and the following

+   disclaimer in the documentation and/or other materials provided

+   with the distribution.

+* Disclaimer. None of the names of Contributor, Intel, or the names

+  of their respective contributors may be used to endorse or

+  promote products derived from this software without specific

+  prior written permission.

+* Contributor grants a license (with the right to sublicense) under

+  claims of Contributor's patents that Contributor can license that

+  are infringed by the Contribution (as delivered by Contributor) to

+  make, use, distribute, sell, offer for sale, and import the

+  Contribution and derivative works thereof solely to the minimum

+  extent necessary for licensee to exercise the granted copyright

+  license; this patent license applies solely to those portions of

+  the Contribution that are unmodified. No hardware per se is

+  licensed.

+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE

+  CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY

+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A

+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+  CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT

+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR

+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE

+  CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH

+  DAMAGE.

+

+== SECTION 3: Representations ==

+* You represent that You are legally entitled to grant the above

+  license. If your employer(s) has rights to intellectual property

+  that You create that includes Your Contributions, You represent

+  that You have received permission to make Contributions on behalf

+  of that employer, that Your employer has waived such rights for

+  Your Contributions.

+* You represent that each of Your Contributions is Your original

+  creation (see Section 4 for submissions on behalf of others).

+  You represent that Your Contribution submissions include complete

+  details of any third-party license or other restriction

+  (including, but not limited to, related patents and trademarks)

+  of which You are personally aware and which are associated with

+  any part of Your Contributions.

+

+== SECTION 4: Third Party Contributions ==

+* Should You wish to submit work that is not Your original creation,

+  You may submit it to TianoCore site separately from any

+  Contribution, identifying the complete details of its source

+  and of any license or other restriction (including, but not

+  limited to, related patents, trademarks, and license agreements)

+  of which You are personally aware, and conspicuously marking the

+  work as "Submitted on behalf of a third-party: [named here]".

+

+== SECTION 5: Miscellaneous ==

+* Applicable Laws. Any claims arising under or relating to this

+  Agreement shall be governed by the internal substantive laws of

+  the State of Delaware or federal courts located in Delaware,

+  without regard to principles of conflict of laws.

+* Language. This Agreement is in the English language only, which

+  language shall be controlling in all respects, and all versions

+  of this Agreement in any other language shall be for accommodation

+  only and shall not be binding. All communications and notices made

+  or given pursuant to this Agreement, and all documentation and

+  support to be provided, unless otherwise noted, shall be in the

+  English language.

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11Lib.c
new file mode 100644
index 0000000..a08b7b1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11Lib.c
@@ -0,0 +1,37 @@
+/** @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.

+

+**/

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  )

+{

+  ASSERT(0); //TODO: Implement me

+}

+

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  )

+{

+  ASSERT(0); //TODO: Implement me

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11MpCoreLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11MpCoreLib.inf
new file mode 100644
index 0000000..3a796c1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11MpCoreLib.inf
@@ -0,0 +1,32 @@
+#/* @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                      = Arm11MpCoreLib

+  FILE_GUID                      = dc8a69e0-6be0-469c-94d3-5e6d71aa9808

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmCpuLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  IoLib

+  PcdLib

+

+[Sources.common]

+  Arm11Lib.c

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
new file mode 100644
index 0000000..a1678fe
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
@@ -0,0 +1,65 @@
+/** @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.

+

+**/

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/ArmGenericTimerCounterLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+#include <Chipset/ArmCortexA15.h>

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  )

+{

+  // Check if Architectural Timer frequency is valid number (should not be 0)

+  ASSERT (PcdGet32 (PcdArmArchTimerFreqInHz));

+  ASSERT(ArmIsArchTimerImplemented () != 0);

+

+  // Enable SWP instructions

+  ArmEnableSWPInstruction ();

+

+  // Enable program flow prediction, if supported.

+  ArmEnableBranchPrediction ();

+

+  // Note: System Counter frequency can only be set in Secure privileged mode,

+  // if security extensions are implemented.

+  ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));

+

+  if (ArmIsMpCore()) {

+    // Turn on SMP coherency

+    ArmSetAuxCrBit (A15_FEATURE_SMP);

+  }

+

+}

+

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  )

+{

+  /*// Make the SCU accessible in Non Secure world

+  if (ArmPlatformIsPrimaryCore (MpId)) {

+    ScuBase = ArmGetScuBaseAddress();

+

+    // Allow NS access to SCU register

+    MmioOr32 (ScuBase + A9_SCU_SACR_OFFSET, 0xf);

+    // Allow NS access to Private Peripherals

+    MmioOr32 (ScuBase + A9_SCU_SSACR_OFFSET, 0xfff);

+  }*/

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
new file mode 100644
index 0000000..bd9a733
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
@@ -0,0 +1,35 @@
+#/* @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                      = ArmCortexA15Lib

+  FILE_GUID                      = 501b1c8f-21d5-4ef5-a565-435b7f0aae2d

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmCpuLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  ArmGenericTimerCounterLib

+  PcdLib

+

+[Sources.common]

+  ArmCortexA15Lib.c

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S
new file mode 100644
index 0000000..e5fbc86
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------

+#

+# 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>

+

+.text

+.align 3

+GCC_ASM_EXPORT (ArmReadCpuExCr)

+GCC_ASM_EXPORT (ArmWriteCpuExCr)

+

+ASM_PFX(ArmReadCpuExCr):

+  mrs   x0, S3_1_c15_c2_1

+  ret

+

+ASM_PFX(ArmWriteCpuExCr):

+  msr   S3_1_c15_c2_1, x0

+  dsb   sy

+  isb

+  ret

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
new file mode 100644
index 0000000..135bd6b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
@@ -0,0 +1,81 @@
+/** @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.

+

+**/

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/ArmGenericTimerCounterLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+#include <Chipset/ArmCortexA5x.h>

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  )

+{

+  // Check if Architectural Timer frequency is valid number (should not be 0)

+  ASSERT (PcdGet32 (PcdArmArchTimerFreqInHz));

+  ASSERT (ArmIsArchTimerImplemented () != 0);

+

+  // Note: System Counter frequency can only be set in Secure privileged mode,

+  // if security extensions are implemented.

+  ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));

+

+  if (ArmIsMpCore ()) {

+    // Turn on SMP coherency

+    ArmSetCpuExCrBit (A5X_FEATURE_SMP);

+  }

+

+  //

+  // If CPU is CortexA57 r0p0 apply Errata: 806969

+  //

+  if ((ArmReadMidr () & ((ARM_CPU_TYPE_MASK << 4) | ARM_CPU_REV_MASK)) ==

+                         ((ARM_CPU_TYPE_A57 << 4) | ARM_CPU_REV(0,0))) {

+    // DisableLoadStoreWB

+    ArmSetCpuActlrBit (1ULL << 49);

+  }

+}

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  )

+{

+}

+

+VOID

+EFIAPI

+ArmSetCpuExCrBit (

+  IN  UINT64    Bits

+  )

+{

+  UINT64 Value;

+  Value =  ArmReadCpuExCr ();

+  Value |= Bits;

+  ArmWriteCpuExCr (Value);

+}

+

+VOID

+EFIAPI

+ArmUnsetCpuExCrBit (

+  IN  UINT64    Bits

+  )

+{

+  UINT64 Value;

+  Value = ArmReadCpuExCr ();

+  Value &= ~Bits;

+  ArmWriteCpuExCr (Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
new file mode 100644
index 0000000..e270220
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
@@ -0,0 +1,38 @@
+#/* @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                      = ArmCortexA5xLib

+  FILE_GUID                      = 08107938-85d8-4967-ba65-b673f708fcb2

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmCpuLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  ArmGenericTimerCounterLib

+  PcdLib

+

+[Sources.common]

+  ArmCortexA5xLib.c

+

+[Sources.AARCH64]

+  AArch64/ArmCortexA5xHelper.S | GCC

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c
new file mode 100644
index 0000000..e0ba1fa
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c
@@ -0,0 +1,41 @@
+/** @file

+

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/DebugLib.h>

+

+#include <Chipset/ArmV7.h>

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  )

+{

+  // Enable SWP instructions

+  ArmEnableSWPInstruction ();

+

+  // Enable program flow prediction, if supported.

+  ArmEnableBranchPrediction ();

+}

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  )

+{

+  // The CortexA8 is a Unicore CPU. We must not initialize SMP for Non Secure Accesses

+  ASSERT(0);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf
new file mode 100644
index 0000000..890958a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf
@@ -0,0 +1,27 @@
+#/* @file

+#  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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmCortexA8Lib

+  FILE_GUID                      = 34b5745e-f575-44ce-ba2e-df0886807c16

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmCpuLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[Sources.common]

+  ArmCortexA8Lib.c

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S
new file mode 100644
index 0000000..5db5861
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S
@@ -0,0 +1,30 @@
+//

+//  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.

+//

+//

+

+#include <AsmMacroIoLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Chipset/ArmCortexA9.h>

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(ArmGetScuBaseAddress)

+

+// IN None

+// OUT r0 = SCU Base Address

+ASM_PFX(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

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm
new file mode 100644
index 0000000..7150834
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm
@@ -0,0 +1,34 @@
+//

+//  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.

+//

+//

+

+#include <AsmMacroIoLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Chipset/ArmCortexA9.h>

+

+  INCLUDE AsmMacroIoLib.inc

+

+  EXPORT  ArmGetScuBaseAddress

+

+  PRESERVE8

+  AREA    ArmCortexA9Helper, CODE, READONLY

+

+// IN None

+// OUT r0 = SCU Base Address

+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

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
new file mode 100644
index 0000000..4fc6a08
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
@@ -0,0 +1,76 @@
+/** @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.

+

+**/

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/ArmPlatformLib.h>

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+

+#include <Chipset/ArmCortexA9.h>

+

+VOID

+ArmEnableScu (

+  VOID

+  )

+{

+  INTN          ScuBase;

+

+  ScuBase = ArmGetScuBaseAddress();

+

+  // Invalidate all: write -1 to SCU Invalidate All register

+  MmioWrite32(ScuBase + A9_SCU_INVALL_OFFSET, 0xffffffff);

+  // Enable SCU

+  MmioWrite32(ScuBase + A9_SCU_CONTROL_OFFSET, 0x1);

+}

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  )

+{

+  // Enable SWP instructions

+  ArmEnableSWPInstruction ();

+

+  // Enable program flow prediction, if supported.

+  ArmEnableBranchPrediction ();

+

+  // If MPCore then Enable the SCU

+  if (ArmIsMpCore()) {

+    // Signals the Cortex-A9 processor is taking part in coherency

+    ArmSetAuxCrBit (A9_FEATURE_SMP);

+

+    ArmEnableScu ();

+  }

+}

+

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  )

+{

+  INTN          ScuBase;

+

+  // Make the SCU accessible in Non Secure world

+  if (ArmPlatformIsPrimaryCore (MpId)) {

+    ScuBase = ArmGetScuBaseAddress();

+

+    // Allow NS access to SCU register

+    MmioOr32 (ScuBase + A9_SCU_SACR_OFFSET, 0xf);

+    // Allow NS access to Private Peripherals

+    MmioOr32 (ScuBase + A9_SCU_SSACR_OFFSET, 0xfff);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
new file mode 100644
index 0000000..236b0bc
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
@@ -0,0 +1,37 @@
+#/* @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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmCortexA9Lib

+  FILE_GUID                      = c9709ea3-1beb-4806-889a-8a1d5e5e1697

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmCpuLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  ArmPlatformLib

+  IoLib

+  PcdLib

+

+[Sources.common]

+  ArmCortexA9Lib.c

+  ArmCortexA9Helper.asm     | RVCT

+  ArmCortexA9Helper.S       | GCC

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
new file mode 100644
index 0000000..9b1815f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
@@ -0,0 +1,39 @@
+/** @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 <Base.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/ArmGenericTimerCounterLib.h>

+#include <Library/PcdLib.h>

+

+#include <Chipset/ArmAemV8.h>

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  )

+{

+  // Note: System Counter frequency can only be set in Secure privileged mode,

+  // if security extensions are implemented.

+  ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));

+}

+

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  )

+{

+  // Nothing to do

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
new file mode 100644
index 0000000..1c81220
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
@@ -0,0 +1,34 @@
+#/* @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                      = ArmCortexAEMv8Lib

+  FILE_GUID                      = 8ab5a7e3-86b1-4dd3-a092-09ee801e774b

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmCpuLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmGenericTimerCounterLib

+  PcdLib

+

+[Sources.common]

+  ArmCortexAEMv8Lib.c

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
new file mode 100644
index 0000000..9da69b2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
@@ -0,0 +1,47 @@
+/** @file

+*

+*  Copyright (c) 2014, ARM Limited. All rights reserved.

+*

+*  This program and the accompanying materials are licensed and made available

+*  under the terms and conditions of the BSD License which accompanies this

+*  distribution.  The full text of the license may be found at

+*  http://opensource.org/licenses/bsd-license.php

+*

+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+*

+**/

+

+#include <Library/ArmLib.h>

+#include <Library/ArmGicLib.h>

+

+#include "GicV3/ArmGicV3Lib.h"

+

+ARM_GIC_ARCH_REVISION

+EFIAPI

+ArmGicGetSupportedArchRevision (

+  VOID

+  )

+{

+  // Ideally we would like to use the GICC IIDR Architecture version here, but

+  // this does not seem to be very reliable as the implementation could easily

+  // get it wrong. It is more reliable to check if the GICv3 System Register

+  // feature is implemented on the CPU. This is also convenient as our GICv3

+  // driver requires SRE. If only Memory mapped access is available we try to

+  // drive the GIC as a v2.

+  if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {

+    // Make sure System Register access is enabled (SRE). This depends on the

+    // higher privilege level giving us permission, otherwise we will either

+    // cause an exception here, or the write doesn't stick in which case we need

+    // to fall back to the GICv2 MMIO interface.

+    // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started

+    // at the same exception level.

+    // It is the OS responsibility to set this bit.

+    ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE);

+    if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) {

+      return ARM_GIC_ARCH_REVISION_3;

+    }

+  }

+

+  return ARM_GIC_ARCH_REVISION_2;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
new file mode 100644
index 0000000..f360a40
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
@@ -0,0 +1,47 @@
+/** @file

+*

+*  Copyright (c) 2014, ARM Limited. All rights reserved.

+*

+*  This program and the accompanying materials are licensed and made available

+*  under the terms and conditions of the BSD License which accompanies this

+*  distribution.  The full text of the license may be found at

+*  http://opensource.org/licenses/bsd-license.php

+*

+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+*

+**/

+

+#include <Library/ArmLib.h>

+#include <Library/ArmGicLib.h>

+

+#include "GicV3/ArmGicV3Lib.h"

+

+ARM_GIC_ARCH_REVISION

+EFIAPI

+ArmGicGetSupportedArchRevision (

+  VOID

+  )

+{

+  // Ideally we would like to use the GICC IIDR Architecture version here, but

+  // this does not seem to be very reliable as the implementation could easily

+  // get it wrong. It is more reliable to check if the GICv3 System Register

+  // feature is implemented on the CPU. This is also convenient as our GICv3

+  // driver requires SRE. If only Memory mapped access is available we try to

+  // drive the GIC as a v2.

+  if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {

+    // Make sure System Register access is enabled (SRE). This depends on the

+    // higher privilege level giving us permission, otherwise we will either

+    // cause an exception here, or the write doesn't stick in which case we need

+    // to fall back to the GICv2 MMIO interface.

+    // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started

+    // at the same exception level.

+    // It is the OS responsibility to set this bit.

+    ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE);

+    if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) {

+      return ARM_GIC_ARCH_REVISION_3;

+    }

+  }

+

+  return ARM_GIC_ARCH_REVISION_2;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
new file mode 100644
index 0000000..a9ccef5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
@@ -0,0 +1,141 @@
+/*++

+

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

+

+VOID

+EFIAPI

+IrqInterruptHandler (

+  IN EFI_EXCEPTION_TYPE           InterruptType,

+  IN EFI_SYSTEM_CONTEXT           SystemContext

+  );

+

+VOID

+EFIAPI

+ExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  );

+

+//

+// Making this global saves a few bytes in image size

+//

+EFI_HANDLE  gHardwareInterruptHandle = NULL;

+

+//

+// Notifications

+//

+EFI_EVENT EfiExitBootServicesEvent      = (EFI_EVENT)NULL;

+

+// Maximum Number of Interrupts

+UINTN mGicNumInterrupts                 = 0;

+

+HARDWARE_INTERRUPT_HANDLER  *gRegisteredInterruptHandlers = NULL;

+

+/**

+  Register Handler for the specified interrupt source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+  @param Handler  Callback for interrupt. NULL to unregister

+

+  @retval EFI_SUCCESS Source was updated to support Handler.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+RegisterInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source,

+  IN HARDWARE_INTERRUPT_HANDLER         Handler

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  gRegisteredInterruptHandlers[Source] = Handler;

+

+  // If the interrupt handler is unregistered then disable the interrupt

+  if (NULL == Handler){

+    return This->DisableInterruptSource (This, Source);

+  } else {

+    return This->EnableInterruptSource (This, Source);

+  }

+}

+

+EFI_STATUS

+InstallAndRegisterInterruptService (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL   *InterruptProtocol,

+  IN EFI_CPU_INTERRUPT_HANDLER          InterruptHandler,

+  IN EFI_EVENT_NOTIFY                   ExitBootServicesEvent

+  )

+{

+  EFI_STATUS               Status;

+  EFI_CPU_ARCH_PROTOCOL   *Cpu;

+

+  // Initialize the array for the Interrupt Handlers

+  gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);

+  if (gRegisteredInterruptHandlers == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &gHardwareInterruptHandle,

+                  &gHardwareInterruptProtocolGuid, InterruptProtocol,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get the CPU protocol that this driver requires.

+  //

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Unregister the default exception handler.

+  //

+  Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Register to receive interrupts

+  //

+  Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  // Register for an ExitBootServicesEvent

+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
new file mode 100644
index 0000000..2bb064f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -0,0 +1,59 @@
+/*++

+

+Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>

+

+This program and the accompanying materials

+are licensed and made available under the terms and conditions of the BSD License

+which accompanies this distribution.  The full text of the license may be found at

+http://opensource.org/licenses/bsd-license.php

+

+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+Module Name:

+

+  ArmGicDxe.c

+

+Abstract:

+

+  Driver implementing the GIC interrupt controller protocol

+

+--*/

+

+#include <PiDxe.h>

+

+#include "ArmGicDxe.h"

+

+/**

+  Initialize the state information for the CPU Architectural Protocol

+

+  @param  ImageHandle   of the loaded driver

+  @param  SystemTable   Pointer to the System Table

+

+  @retval EFI_SUCCESS           Protocol registered

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Hardware problems

+  @retval EFI_UNSUPPORTED       GIC version not supported

+

+**/

+EFI_STATUS

+InterruptDxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_STATUS            Status;

+  ARM_GIC_ARCH_REVISION Revision;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+

+  if (Revision == ARM_GIC_ARCH_REVISION_2) {

+    Status = GicV2DxeInitialize (ImageHandle, SystemTable);

+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {

+    Status = GicV3DxeInitialize (ImageHandle, SystemTable);

+  } else {

+    Status = EFI_UNSUPPORTED;

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.h b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.h
new file mode 100644
index 0000000..af33aa9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.h
@@ -0,0 +1,67 @@
+/*++

+

+Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>

+

+This program and the accompanying materials

+are licensed and made available under the terms and conditions of the BSD License

+which accompanies this distribution.  The full text of the license may be found at

+http://opensource.org/licenses/bsd-license.php

+

+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+--*/

+

+#ifndef __ARM_GIC_DXE_H__

+#define __ARM_GIC_DXE_H__

+

+#include <Library/ArmGicLib.h>

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+#include <Protocol/Cpu.h>

+#include <Protocol/HardwareInterrupt.h>

+

+extern UINTN                        mGicNumInterrupts;

+extern HARDWARE_INTERRUPT_HANDLER  *gRegisteredInterruptHandlers;

+

+//

+// Common API

+//

+EFI_STATUS

+InstallAndRegisterInterruptService (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL   *InterruptProtocol,

+  IN EFI_CPU_INTERRUPT_HANDLER          InterruptHandler,

+  IN EFI_EVENT_NOTIFY                   ExitBootServicesEvent

+  );

+

+EFI_STATUS

+EFIAPI

+RegisterInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source,

+  IN HARDWARE_INTERRUPT_HANDLER         Handler

+  );

+

+//

+// GicV2 API

+//

+EFI_STATUS

+GicV2DxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  );

+

+//

+// GicV3 API

+//

+EFI_STATUS

+GicV3DxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
new file mode 100644
index 0000000..e554301
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
@@ -0,0 +1,60 @@
+#/** @file

+#

+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#  Copyright (c) 2012 - 2015, ARM Ltd. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmGicDxe

+  FILE_GUID                      = DE371F7C-DEC4-4D21-ADF1-593ABCC15882

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InterruptDxeInitialize

+

+[Sources.common]

+  ArmGicDxe.c

+  ArmGicCommonDxe.c

+

+  GicV2/ArmGicV2Dxe.c

+  GicV3/ArmGicV3Dxe.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmGicLib

+  BaseLib

+  UefiLib

+  UefiBootServicesTableLib

+  DebugLib

+  PrintLib

+  MemoryAllocationLib

+  UefiDriverEntryPoint

+  IoLib

+  PcdLib

+

+[Protocols]

+  gHardwareInterruptProtocolGuid

+  gEfiCpuArchProtocolGuid

+

+[Pcd.common]

+  gArmTokenSpaceGuid.PcdGicDistributorBase

+  gArmTokenSpaceGuid.PcdGicRedistributorsBase

+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase

+  gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy

+

+[Depex]

+  gEfiCpuArchProtocolGuid

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c
new file mode 100644
index 0000000..48708e3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -0,0 +1,314 @@
+/** @file

+*

+*  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.

+*

+**/

+

+#include <Base.h>

+#include <Library/ArmGicLib.h>

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+

+#include "GicV2/ArmGicV2Lib.h"

+#include "GicV3/ArmGicV3Lib.h"

+

+/**

+ * Return the base address of the GIC redistributor for the current CPU

+ *

+ * @param Revision  GIC Revision. The GIC redistributor might have a different

+ *                  granularity following the GIC revision.

+ *

+ * @retval Base address of the associated GIC Redistributor

+ */

+STATIC

+UINTN

+GicGetCpuRedistributorBase (

+  IN UINTN                 GicRedistributorBase,

+  IN ARM_GIC_ARCH_REVISION Revision

+  )

+{

+  UINTN Index;

+  UINTN MpId;

+  UINTN CpuAffinity;

+  UINTN Affinity;

+  UINTN GicRedistributorGranularity;

+  UINTN GicCpuRedistributorBase;

+

+  MpId = ArmReadMpidr ();

+  // Define CPU affinity as Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]

+  // whereas Affinity3 is defined at [32:39] in MPIDR

+  CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | ((MpId & ARM_CORE_AFF3) >> 8);

+

+  if (Revision == ARM_GIC_ARCH_REVISION_3) {

+    // 2 x 64KB frame: Redistributor control frame + SGI Control & Generation frame

+    GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_SGI_PPI_FRAME_SIZE;

+  } else {

+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);

+    return 0;

+  }

+

+  GicCpuRedistributorBase = GicRedistributorBase;

+

+  for (Index = 0; Index < PcdGet32 (PcdCoreCount); Index++) {

+    Affinity = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER) >> 32;

+    if (Affinity == CpuAffinity) {

+      return GicCpuRedistributorBase;

+    }

+

+    // Move to the next GIC Redistributor frame

+    GicRedistributorBase += GicRedistributorGranularity;

+  }

+

+  // The Redistributor has not been found for the current CPU

+  ASSERT_EFI_ERROR (EFI_NOT_FOUND);

+  return 0;

+}

+

+UINTN

+EFIAPI

+ArmGicGetInterfaceIdentification (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  // Read the GIC Identification Register

+  return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIIDR);

+}

+

+UINTN

+EFIAPI

+ArmGicGetMaxNumInterrupts (

+  IN  INTN          GicDistributorBase

+  )

+{

+  return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);

+}

+

+VOID

+EFIAPI

+ArmGicSendSgiTo (

+  IN  INTN          GicDistributorBase,

+  IN  INTN          TargetListFilter,

+  IN  INTN          CPUTargetList,

+  IN  INTN          SgiId

+  )

+{

+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);

+}

+

+/*

+ * Acknowledge and return the value of the Interrupt Acknowledge Register

+ *

+ * InterruptId is returned separately from the register value because in

+ * the GICv2 the register value contains the CpuId and InterruptId while

+ * in the GICv3 the register value is only the InterruptId.

+ *

+ * @param GicInterruptInterfaceBase   Base Address of the GIC CPU Interface

+ * @param InterruptId                 InterruptId read from the Interrupt Acknowledge Register

+ *

+ * @retval value returned by the Interrupt Acknowledge Register

+ *

+ */

+UINTN

+EFIAPI

+ArmGicAcknowledgeInterrupt (

+  IN  UINTN          GicInterruptInterfaceBase,

+  OUT UINTN          *InterruptId

+  )

+{

+  UINTN Value;

+  ARM_GIC_ARCH_REVISION Revision;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if (Revision == ARM_GIC_ARCH_REVISION_2) {

+    Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);

+    // InterruptId is required for the caller to know if a valid or spurious

+    // interrupt has been read

+    ASSERT (InterruptId != NULL);

+    if (InterruptId != NULL) {

+      *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;

+    }

+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {

+    Value = ArmGicV3AcknowledgeInterrupt ();

+  } else {

+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);

+    // Report Spurious interrupt which is what the above controllers would

+    // return if no interrupt was available

+    Value = 1023;

+  }

+

+  return Value;

+}

+

+VOID

+EFIAPI

+ArmGicEndOfInterrupt (

+  IN  UINTN                 GicInterruptInterfaceBase,

+  IN UINTN                  Source

+  )

+{

+  ARM_GIC_ARCH_REVISION Revision;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if (Revision == ARM_GIC_ARCH_REVISION_2) {

+    ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);

+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {

+    ArmGicV3EndOfInterrupt (Source);

+  } else {

+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);

+  }

+}

+

+VOID

+EFIAPI

+ArmGicEnableInterrupt (

+  IN UINTN                  GicDistributorBase,

+  IN UINTN                  GicRedistributorBase,

+  IN UINTN                  Source

+  )

+{

+  UINT32                RegOffset;

+  UINTN                 RegShift;

+  ARM_GIC_ARCH_REVISION Revision;

+  UINTN                 GicCpuRedistributorBase;

+

+  // Calculate enable register offset and bit position

+  RegOffset = Source / 32;

+  RegShift = Source % 32;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {

+    // Write set-enable register

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);

+  } else {

+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);

+    if (GicCpuRedistributorBase == 0) {

+      ASSERT_EFI_ERROR (EFI_NOT_FOUND);

+      return;

+    }

+

+    // Write set-enable register

+    MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset), 1 << RegShift);

+  }

+}

+

+VOID

+EFIAPI

+ArmGicDisableInterrupt (

+  IN UINTN                  GicDistributorBase,

+  IN UINTN                  GicRedistributorBase,

+  IN UINTN                  Source

+  )

+{

+  UINT32                RegOffset;

+  UINTN                 RegShift;

+  ARM_GIC_ARCH_REVISION Revision;

+  UINTN                 GicCpuRedistributorBase;

+

+  // Calculate enable register offset and bit position

+  RegOffset = Source / 32;

+  RegShift = Source % 32;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {

+    // Write clear-enable register

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);

+  } else {

+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);

+    if (GicCpuRedistributorBase == 0) {

+      return;

+    }

+

+    // Write clear-enable register

+    MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * RegOffset), 1 << RegShift);

+  }

+}

+

+BOOLEAN

+EFIAPI

+ArmGicIsInterruptEnabled (

+  IN UINTN                  GicDistributorBase,

+  IN UINTN                  GicRedistributorBase,

+  IN UINTN                  Source

+  )

+{

+  UINT32                RegOffset;

+  UINTN                 RegShift;

+  ARM_GIC_ARCH_REVISION Revision;

+  UINTN                 GicCpuRedistributorBase;

+  UINT32                Interrupts;

+

+  // Calculate enable register offset and bit position

+  RegOffset = Source / 32;

+  RegShift = Source % 32;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {

+    Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);

+  } else {

+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);

+    if (GicCpuRedistributorBase == 0) {

+      return 0;

+    }

+

+    // Read set-enable register

+    Interrupts = MmioRead32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset));

+  }

+

+  return ((Interrupts & (1 << RegShift)) != 0);

+}

+

+VOID

+EFIAPI

+ArmGicDisableDistributor (

+  IN  INTN          GicDistributorBase

+  )

+{

+  // Disable Gic Distributor

+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x0);

+}

+

+VOID

+EFIAPI

+ArmGicEnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  ARM_GIC_ARCH_REVISION Revision;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if (Revision == ARM_GIC_ARCH_REVISION_2) {

+    ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);

+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {

+    ArmGicV3EnableInterruptInterface ();

+  } else {

+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);

+  }

+}

+

+VOID

+EFIAPI

+ArmGicDisableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  ARM_GIC_ARCH_REVISION Revision;

+

+  Revision = ArmGicGetSupportedArchRevision ();

+  if (Revision == ARM_GIC_ARCH_REVISION_2) {

+    ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);

+  } else if (Revision == ARM_GIC_ARCH_REVISION_3) {

+    ArmGicV3DisableInterruptInterface ();

+  } else {

+    ASSERT_EFI_ERROR (EFI_UNSUPPORTED);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
new file mode 100644
index 0000000..2ae3fd3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
@@ -0,0 +1,52 @@
+#/* @file

+#  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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmGicLib

+  FILE_GUID                      = 03d05ee4-cdeb-458c-9dfc-993f09bdf405

+  MODULE_TYPE                    = SEC

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmGicLib

+

+[Sources]

+  ArmGicLib.c

+  ArmGicNonSecLib.c

+

+  GicV2/ArmGicV2Lib.c

+  GicV2/ArmGicV2NonSecLib.c

+

+[Sources.ARM]

+  Arm/ArmGicArchLib.c

+  GicV3/Arm/ArmGicV3.S     | GCC

+  GicV3/Arm/ArmGicV3.asm   | RVCT

+

+[Sources.AARCH64]

+  AArch64/ArmGicArchLib.c

+  GicV3/AArch64/ArmGicV3.S

+

+[LibraryClasses]

+  ArmLib

+  DebugLib

+  IoLib

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  MdePkg/MdePkg.dec

+

+[Pcd]

+  gArmPlatformTokenSpaceGuid.PcdCoreCount

+

+[FeaturePcd]

+  gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
new file mode 100644
index 0000000..e2538f1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
@@ -0,0 +1,37 @@
+/** @file

+*

+*  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.

+*

+**/

+

+#include <Uefi.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+VOID

+EFIAPI

+ArmGicEnableDistributor (

+  IN  INTN          GicDistributorBase

+  )

+{

+  ARM_GIC_ARCH_REVISION Revision;

+

+  /*

+   * Enable GIC distributor in Non-Secure world.

+   * Note: The ICDDCR register is banked when Security extensions are implemented

+   */

+  Revision = ArmGicGetSupportedArchRevision ();

+  if (Revision == ARM_GIC_ARCH_REVISION_2) {

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);

+  } else {

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
new file mode 100644
index 0000000..1fdd4d7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
@@ -0,0 +1,66 @@
+/** @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.

+*

+**/

+

+#include <Base.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+#include "GicV2/ArmGicV2Lib.h"

+

+/*

+ * This function configures the interrupts set by the mask to be secure.

+ *

+ */

+VOID

+EFIAPI

+ArmGicSetSecureInterrupts (

+  IN  UINTN         GicDistributorBase,

+  IN  UINTN*        GicSecureInterruptMask,

+  IN  UINTN         GicSecureInterruptMaskSize

+  )

+{

+  UINTN  Index;

+  UINT32 InterruptStatus;

+

+  // We must not have more interrupts defined by the mask than the number of available interrupts

+  ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));

+

+  // Set all the interrupts defined by the mask as Secure

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

+    InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));

+  }

+}

+

+VOID

+EFIAPI

+ArmGicEnableDistributor (

+  IN  INTN          GicDistributorBase

+  )

+{

+  // Turn on the GIC distributor

+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);

+}

+

+VOID

+EFIAPI

+ArmGicSetupNonSecure (

+  IN  UINTN         MpId,

+  IN  INTN          GicDistributorBase,

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  ArmGicV2SetupNonSecure (MpId, GicDistributorBase, GicInterruptInterfaceBase);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
new file mode 100644
index 0000000..7d4e49e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
@@ -0,0 +1,53 @@
+#/* @file

+#  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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmGicSecLib

+  FILE_GUID                      = 85f3cf80-b5f4-11df-9855-0002a5d5c51b

+  MODULE_TYPE                    = SEC

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmGicLib

+

+[Sources]

+  ArmGicLib.c

+  ArmGicSecLib.c

+

+  GicV2/ArmGicV2Lib.c

+  GicV2/ArmGicV2SecLib.c

+

+[Sources.ARM]

+  Arm/ArmGicArchLib.c

+  GicV3/Arm/ArmGicV3.S     | GCC

+  GicV3/Arm/ArmGicV3.asm   | RVCT

+

+[Sources.AARCH64]

+  AArch64/ArmGicArchLib.c

+  GicV3/AArch64/ArmGicV3.S

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+

+[LibraryClasses]

+  ArmLib

+  DebugLib

+  IoLib

+

+[Pcd]

+  gArmPlatformTokenSpaceGuid.PcdCoreCount

+

+[FeaturePcd]

+  gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
new file mode 100644
index 0000000..743c534
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
@@ -0,0 +1,317 @@
+/*++

+

+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>

+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+Portions 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.

+

+Module Name:

+

+  GicV2/ArmGicV2Dxe.c

+

+Abstract:

+

+  Driver implementing the GicV2 interrupt controller protocol

+

+--*/

+

+#include "ArmGicDxe.h"

+#include "GicV2/ArmGicV2Lib.h"

+

+#define ARM_GIC_DEFAULT_PRIORITY  0x80

+

+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;

+

+STATIC UINT32 mGicInterruptInterfaceBase;

+STATIC UINT32 mGicDistributorBase;

+

+/**

+  Enable interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt enabled.

+  @retval EFI_UNSUPPORTED   Source interrupt is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+GicV2EnableInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmGicEnableInterrupt (mGicDistributorBase, 0, Source);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Disable interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt disabled.

+  @retval EFI_UNSUPPORTED   Source interrupt is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+GicV2DisableInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmGicDisableInterrupt (mGicDistributorBase, 0, Source);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return current state of interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+  @param InterruptState  TRUE: source enabled, FALSE: source disabled.

+

+  @retval EFI_SUCCESS       InterruptState is valid

+  @retval EFI_UNSUPPORTED   Source interrupt is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+GicV2GetInterruptSourceState (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source,

+  IN BOOLEAN                            *InterruptState

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, 0, Source);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Signal to the hardware that the End Of Interrupt state

+  has been reached.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt EOI'ed.

+  @retval EFI_UNSUPPORTED   Source interrupt is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+GicV2EndOfInterrupt (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmGicV2EndOfInterrupt (mGicInterruptInterfaceBase, Source);

+  return EFI_SUCCESS;

+}

+

+/**

+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.

+

+  @param  InterruptType    Defines the type of interrupt or exception that

+                           occurred on the processor.This parameter is processor architecture specific.

+  @param  SystemContext    A pointer to the processor context when

+                           the interrupt occurred on the processor.

+

+  @return None

+

+**/

+VOID

+EFIAPI

+GicV2IrqInterruptHandler (

+  IN EFI_EXCEPTION_TYPE           InterruptType,

+  IN EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  UINT32                      GicInterrupt;

+  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;

+

+  GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);

+

+  // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).

+  if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {

+    // The special interrupt do not need to be acknowledge

+    return;

+  }

+

+  InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];

+  if (InterruptHandler != NULL) {

+    // Call the registered interrupt handler.

+    InterruptHandler (GicInterrupt, SystemContext);

+  } else {

+    DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));

+  }

+

+  GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);

+}

+

+//

+// The protocol instance produced by this driver

+//

+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {

+  RegisterInterruptSource,

+  GicV2EnableInterruptSource,

+  GicV2DisableInterruptSource,

+  GicV2GetInterruptSourceState,

+  GicV2EndOfInterrupt

+};

+

+/**

+  Shutdown our hardware

+

+  DXE Core will disable interrupts and turn off the timer and disable interrupts

+  after all the event handlers have run.

+

+  @param[in]  Event   The Event that is being processed

+  @param[in]  Context Event Context

+**/

+VOID

+EFIAPI

+GicV2ExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  UINTN    Index;

+  UINT32   GicInterrupt;

+

+  // Disable all the interrupts

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

+    GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);

+  }

+

+  // Acknowledge all pending interrupts

+  do {

+    GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);

+

+    if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) {

+      GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);

+    }

+  } while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt));

+

+  // Disable Gic Interface

+  ArmGicV2DisableInterruptInterface (mGicInterruptInterfaceBase);

+

+  // Disable Gic Distributor

+  ArmGicDisableDistributor (mGicDistributorBase);

+}

+

+/**

+  Initialize the state information for the CPU Architectural Protocol

+

+  @param  ImageHandle   of the loaded driver

+  @param  SystemTable   Pointer to the System Table

+

+  @retval EFI_SUCCESS           Protocol registered

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Hardware problems

+

+**/

+EFI_STATUS

+GicV2DxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+  UINTN                   Index;

+  UINT32                  RegOffset;

+  UINTN                   RegShift;

+  UINT32                  CpuTarget;

+

+  // Make sure the Interrupt Controller Protocol is not already installed in the system.

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);

+

+  mGicInterruptInterfaceBase = PcdGet32 (PcdGicInterruptInterfaceBase);

+  mGicDistributorBase = PcdGet32 (PcdGicDistributorBase);

+  mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);

+

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

+    GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);

+

+    // Set Priority

+    RegOffset = Index / 4;

+    RegShift = (Index % 4) * 8;

+    MmioAndThenOr32 (

+      mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),

+      ~(0xff << RegShift),

+      ARM_GIC_DEFAULT_PRIORITY << RegShift

+      );

+  }

+

+  //

+  // Targets the interrupts to the Primary Cpu

+  //

+

+  // Only Primary CPU will run this code. We can identify our GIC CPU ID by reading

+  // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each

+  // connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.

+  // More Info in the GIC Specification about "Interrupt Processor Targets Registers"

+  //

+  // Read the first Interrupt Processor Targets Register (that corresponds to the 4

+  // first SGIs)

+  CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);

+

+  // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value

+  // is 0 when we run on a uniprocessor platform.

+  if (CpuTarget != 0) {

+    // The 8 first Interrupt Processor Targets Registers are read-only

+    for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {

+      MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);

+    }

+  }

+

+  // Set binary point reg to 0x7 (no preemption)

+  MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCBPR, 0x7);

+

+  // Set priority mask reg to 0xff to allow all priorities through

+  MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0xff);

+

+  // Enable gic cpu interface

+  ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase);

+

+  // Enable gic distributor

+  ArmGicEnableDistributor (mGicDistributorBase);

+

+  Status = InstallAndRegisterInterruptService (

+          &gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
new file mode 100644
index 0000000..5ac1d89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
@@ -0,0 +1,36 @@
+/** @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 <Library/ArmGicLib.h>

+#include <Library/IoLib.h>

+

+UINTN

+EFIAPI

+ArmGicV2AcknowledgeInterrupt (

+  IN  UINTN          GicInterruptInterfaceBase

+  )

+{

+  // Read the Interrupt Acknowledge Register

+  return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);

+}

+

+VOID

+EFIAPI

+ArmGicV2EndOfInterrupt (

+  IN  UINTN                 GicInterruptInterfaceBase,

+  IN UINTN                  Source

+  )

+{

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
new file mode 100644
index 0000000..6803467
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
@@ -0,0 +1,54 @@
+/** @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.

+*

+**/

+

+#ifndef _ARM_GIC_V2_H_

+#define _ARM_GIC_V2_H_

+

+// Interrupts from 1020 to 1023 are considered as special interrupts (eg: spurious interrupts)

+#define ARM_GIC_IS_SPECIAL_INTERRUPTS(Interrupt) (((Interrupt) >= 1020) && ((Interrupt) <= 1023))

+

+VOID

+EFIAPI

+ArmGicV2SetupNonSecure (

+  IN  UINTN         MpId,

+  IN  INTN          GicDistributorBase,

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+VOID

+EFIAPI

+ArmGicV2EnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+VOID

+EFIAPI

+ArmGicV2DisableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+UINTN

+EFIAPI

+ArmGicV2AcknowledgeInterrupt (

+  IN  UINTN          GicInterruptInterfaceBase

+  );

+

+VOID

+EFIAPI

+ArmGicV2EndOfInterrupt (

+  IN UINTN                  GicInterruptInterfaceBase,

+  IN UINTN                  Source

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
new file mode 100644
index 0000000..92b764f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
@@ -0,0 +1,42 @@
+/** @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.

+*

+**/

+

+#include <Uefi.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+

+VOID

+EFIAPI

+ArmGicV2EnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  /*

+  * Enable the CPU interface in Non-Secure world

+  * Note: The ICCICR register is banked when Security extensions are implemented

+  */

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1);

+}

+

+VOID

+EFIAPI

+ArmGicV2DisableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  // Disable Gic Interface

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x0);

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x0);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c
new file mode 100644
index 0000000..ac1e0e4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c
@@ -0,0 +1,100 @@
+/** @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.

+*

+**/

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmPlatformLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+/*

+ * This function configures the all interrupts to be Non-secure.

+ *

+ */

+VOID

+EFIAPI

+ArmGicV2SetupNonSecure (

+  IN  UINTN         MpId,

+  IN  INTN          GicDistributorBase,

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  UINTN InterruptId;

+  UINTN CachedPriorityMask;

+  UINTN Index;

+  UINTN MaxInterrupts;

+

+  CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);

+

+  // Set priority Mask so that no interrupts get through to CPU

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);

+

+  InterruptId   = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);

+  MaxInterrupts = ArmGicGetMaxNumInterrupts (GicDistributorBase);

+

+  // Only try to clear valid interrupts. Ignore spurious interrupts.

+  while ((InterruptId & 0x3FF) < MaxInterrupts) {

+    // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal

+    ArmGicEndOfInterrupt (GicInterruptInterfaceBase, InterruptId);

+

+    // Next

+    InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);

+  }

+

+  // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).

+  if (ArmPlatformIsPrimaryCore (MpId)) {

+    // Ensure all GIC interrupts are Non-Secure

+    for (Index = 0; Index < (MaxInterrupts / 32); Index++) {

+      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);

+    }

+  } else {

+    // The secondary cores only set the Non Secure bit to their banked PPIs

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);

+  }

+

+  // Ensure all interrupts can get through the priority mask

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);

+}

+

+VOID

+EFIAPI

+ArmGicV2EnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  // Set Priority Mask to allow interrupts

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);

+

+  // Enable CPU interface in Secure world

+  // Enable CPU interface in Non-secure World

+  // Signal Secure Interrupts to CPU using FIQ line *

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,

+      ARM_GIC_ICCICR_ENABLE_SECURE |

+      ARM_GIC_ICCICR_ENABLE_NS |

+      ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);

+}

+

+VOID

+EFIAPI

+ArmGicV2DisableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  UINT32    ControlValue;

+

+  // Disable CPU interface in Secure world and Non-secure World

+  ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
new file mode 100644
index 0000000..c30ae76
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
@@ -0,0 +1,114 @@
+#

+#  Copyright (c) 2014, ARM Limited. All rights reserved.

+#

+#  This program and the accompanying materials are licensed and made available

+#  under the terms and conditions of the BSD License which accompanies this

+#  distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+

+#include <AsmMacroIoLibV8.h>

+

+#define ICC_SRE_EL1             S3_0_C12_C12_5

+#define ICC_SRE_EL2             S3_4_C12_C9_5

+#define ICC_SRE_EL3             S3_6_C12_C12_5

+#define ICC_IGRPEN1_EL1         S3_0_C12_C12_7

+#define ICC_EOIR1_EL1           S3_0_C12_C12_1

+#define ICC_IAR1_EL1            S3_0_C12_C12_0

+#define ICC_PMR_EL1             S3_0_C4_C6_0

+#define ICC_BPR1_EL1            S3_0_C12_C12_3

+

+.text

+.align 2

+

+GCC_ASM_EXPORT(ArmGicV3GetControlSystemRegisterEnable)

+GCC_ASM_EXPORT(ArmGicV3SetControlSystemRegisterEnable)

+GCC_ASM_EXPORT(ArmGicV3EnableInterruptInterface)

+GCC_ASM_EXPORT(ArmGicV3DisableInterruptInterface)

+GCC_ASM_EXPORT(ArmGicV3EndOfInterrupt)

+GCC_ASM_EXPORT(ArmGicV3AcknowledgeInterrupt)

+GCC_ASM_EXPORT(ArmGicV3SetPriorityMask)

+GCC_ASM_EXPORT(ArmGicV3SetBinaryPointer)

+

+//UINT32

+//EFIAPI

+//ArmGicV3GetControlSystemRegisterEnable (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3GetControlSystemRegisterEnable):

+        EL1_OR_EL2_OR_EL3(x1)

+1:  mrs x0, ICC_SRE_EL1

+        b       4f

+2:  mrs x0, ICC_SRE_EL2

+        b       4f

+3:  mrs x0, ICC_SRE_EL3

+4:  ret

+

+//VOID

+//EFIAPI

+//ArmGicV3SetControlSystemRegisterEnable (

+//  IN UINT32         ControlSystemRegisterEnable

+//  );

+ASM_PFX(ArmGicV3SetControlSystemRegisterEnable):

+        EL1_OR_EL2_OR_EL3(x1)

+1:  msr ICC_SRE_EL1, x0

+        b       4f

+2:  msr ICC_SRE_EL2, x0

+        b       4f

+3:  msr ICC_SRE_EL3, x0

+4:  isb

+        ret

+

+//VOID

+//ArmGicV3EnableInterruptInterface (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3EnableInterruptInterface):

+        mov     x0, #1

+        msr     ICC_IGRPEN1_EL1, x0

+        ret

+

+//VOID

+//ArmGicV3DisableInterruptInterface (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3DisableInterruptInterface):

+        mov     x0, #0

+        msr     ICC_IGRPEN1_EL1, x0

+        ret

+

+//VOID

+//ArmGicV3EndOfInterrupt (

+//  IN UINTN          InterruptId

+//  );

+ASM_PFX(ArmGicV3EndOfInterrupt):

+        msr     ICC_EOIR1_EL1, x0

+        ret

+

+//UINTN

+//ArmGicV3AcknowledgeInterrupt (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3AcknowledgeInterrupt):

+        mrs     x0, ICC_IAR1_EL1

+        ret

+

+//VOID

+//ArmGicV3SetPriorityMask (

+//  IN UINTN          Priority

+//  );

+ASM_PFX(ArmGicV3SetPriorityMask):

+        msr     ICC_PMR_EL1, x0

+        ret

+

+//VOID

+//ArmGicV3SetBinaryPointer (

+//  IN UINTN          BinaryPoint

+//  );

+ASM_PFX(ArmGicV3SetBinaryPointer):

+        msr     ICC_BPR1_EL1, x0

+        ret

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
new file mode 100644
index 0000000..af14b91
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
@@ -0,0 +1,98 @@
+#

+#  Copyright (c) 2014, ARM Limited. All rights reserved.

+#

+#  This program and the accompanying materials are licensed and made available

+#  under the terms and conditions of the BSD License which accompanies this

+#  distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+

+#include <AsmMacroIoLib.h>

+#include <Library/ArmLib.h>

+

+// For the moment we assume this will run in SVC mode on ARMv7

+

+.text

+.align 2

+

+GCC_ASM_EXPORT(ArmGicV3GetControlSystemRegisterEnable)

+GCC_ASM_EXPORT(ArmGicV3SetControlSystemRegisterEnable)

+GCC_ASM_EXPORT(ArmGicV3EnableInterruptInterface)

+GCC_ASM_EXPORT(ArmGicV3DisableInterruptInterface)

+GCC_ASM_EXPORT(ArmGicV3EndOfInterrupt)

+GCC_ASM_EXPORT(ArmGicV3AcknowledgeInterrupt)

+GCC_ASM_EXPORT(ArmGicV3SetPriorityMask)

+GCC_ASM_EXPORT(ArmGicV3SetBinaryPointer)

+

+//UINT32

+//EFIAPI

+//ArmGicGetControlSystemRegisterEnable (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3GetControlSystemRegisterEnable):

+        mrc     p15, 0, r0, c12, c12, 5 // ICC_SRE

+        bx      lr

+

+//VOID

+//EFIAPI

+//ArmGicSetControlSystemRegisterEnable (

+//  IN UINT32         ControlSystemRegisterEnable

+//  );

+ASM_PFX(ArmGicV3SetControlSystemRegisterEnable):

+        mcr     p15, 0, r0, c12, c12, 5 // ICC_SRE

+        isb

+        bx      lr

+

+//VOID

+//ArmGicV3EnableInterruptInterface (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3EnableInterruptInterface):

+        mov     r0, #1

+        mcr     p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1

+        bx      lr

+

+//VOID

+//ArmGicV3DisableInterruptInterface (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3DisableInterruptInterface):

+        mov     r0, #0

+        mcr     p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1

+        bx      lr

+

+//VOID

+//ArmGicV3EndOfInterrupt (

+//  IN UINTN InterruptId

+//  );

+ASM_PFX(ArmGicV3EndOfInterrupt):

+        mcr     p15, 0, r0, c12, c12, 1 //ICC_EOIR1

+        bx      lr

+

+//UINTN

+//ArmGicV3AcknowledgeInterrupt (

+//  VOID

+//  );

+ASM_PFX(ArmGicV3AcknowledgeInterrupt):

+        mrc     p15, 0, r0, c12, c8, 0 //ICC_IAR1

+        bx      lr

+

+//VOID

+//ArmGicV3SetPriorityMask (

+//  IN UINTN                  Priority

+//  );

+ASM_PFX(ArmGicV3SetPriorityMask):

+        mcr     p15, 0, r0, c4, c6, 0 //ICC_PMR

+        bx      lr

+

+//VOID

+//ArmGicV3SetBinaryPointer (

+//  IN UINTN                  BinaryPoint

+//  );

+ASM_PFX(ArmGicV3SetBinaryPointer):

+        mcr     p15, 0, r0, c12, c12, 3 //ICC_BPR1

+        bx      lr

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
new file mode 100644
index 0000000..92c3236
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
@@ -0,0 +1,96 @@
+//

+//  Copyright (c) 2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials are licensed and made available

+//  under the terms and conditions of the BSD License which accompanies this

+//  distribution. The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+// For the moment we assume this will run in SVC mode on ARMv7

+

+    EXPORT  ArmGicV3GetControlSystemRegisterEnable

+    EXPORT  ArmGicV3SetControlSystemRegisterEnable

+    EXPORT  ArmGicV3EnableInterruptInterface

+    EXPORT  ArmGicV3DisableInterruptInterface

+    EXPORT  ArmGicV3EndOfInterrupt

+    EXPORT  ArmGicV3AcknowledgeInterrupt

+    EXPORT  ArmGicV3SetPriorityMask

+    EXPORT  ArmGicV3SetBinaryPointer

+

+    AREA ArmGicV3, CODE, READONLY

+

+//UINT32

+//EFIAPI

+//ArmGicGetControlSystemRegisterEnable (

+//  VOID

+//  );

+ArmGicV3GetControlSystemRegisterEnable

+        mrc     p15, 0, r0, c12, c12, 5 // ICC_SRE

+        bx      lr

+

+//VOID

+//EFIAPI

+//ArmGicSetControlSystemRegisterEnable (

+//  IN UINT32         ControlSystemRegisterEnable

+//  );

+ArmGicV3SetControlSystemRegisterEnable

+        mcr     p15, 0, r0, c12, c12, 5 // ICC_SRE

+        isb

+        bx      lr

+

+//VOID

+//ArmGicV3EnableInterruptInterface (

+//  VOID

+//  );

+ArmGicV3EnableInterruptInterface

+        mov     r0, #1

+        mcr     p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1

+        bx      lr

+

+//VOID

+//ArmGicV3DisableInterruptInterface (

+//  VOID

+//  );

+ArmGicV3DisableInterruptInterface

+        mov     r0, #0

+        mcr     p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1

+        bx      lr

+

+//VOID

+//ArmGicV3EndOfInterrupt (

+//  IN UINTN InterruptId

+//  );

+ArmGicV3EndOfInterrupt

+        mcr     p15, 0, r0, c12, c12, 1 //ICC_EOIR1

+        bx      lr

+

+//UINTN

+//ArmGicV3AcknowledgeInterrupt (

+//  VOID

+//  );

+ArmGicV3AcknowledgeInterrupt

+        mrc     p15, 0, r0, c12, c8, 0 //ICC_IAR1

+        bx      lr

+

+//VOID

+//ArmGicV3SetPriorityMask (

+//  IN UINTN                  Priority

+//  );

+ArmGicV3SetPriorityMask

+        mcr     p15, 0, r0, c4, c6, 0 //ICC_PMR

+        bx      lr

+

+//VOID

+//ArmGicV3SetBinaryPointer (

+//  IN UINTN                  BinaryPoint

+//  );

+ArmGicV3SetBinaryPointer

+        mcr     p15, 0, r0, c12, c12, 3 //ICC_BPR1

+        bx      lr

+

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
new file mode 100644
index 0000000..f3bf191
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
@@ -0,0 +1,301 @@
+/** @file

+*

+*  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.

+*

+**/

+

+#include "ArmGicDxe.h"

+#include "GicV3/ArmGicV3Lib.h"

+

+#define ARM_GIC_DEFAULT_PRIORITY  0x80

+

+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol;

+

+STATIC UINTN mGicDistributorBase;

+STATIC UINTN mGicRedistributorsBase;

+

+/**

+  Enable interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt enabled.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+GicV3EnableInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmGicEnableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Disable interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt disabled.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+GicV3DisableInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmGicDisableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return current state of interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+  @param InterruptState  TRUE: source enabled, FALSE: source disabled.

+

+  @retval EFI_SUCCESS       InterruptState is valid

+  @retval EFI_DEVICE_ERROR  InterruptState is not valid

+

+**/

+EFI_STATUS

+EFIAPI

+GicV3GetInterruptSourceState (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source,

+  IN BOOLEAN                            *InterruptState

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, mGicRedistributorsBase, Source);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Signal to the hardware that the End Of Interrupt state

+  has been reached.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt EOI'ed.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+GicV3EndOfInterrupt (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmGicV3EndOfInterrupt (Source);

+  return EFI_SUCCESS;

+}

+

+/**

+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.

+

+  @param  InterruptType    Defines the type of interrupt or exception that

+                           occurred on the processor.This parameter is processor architecture specific.

+  @param  SystemContext    A pointer to the processor context when

+                           the interrupt occurred on the processor.

+

+  @return None

+

+**/

+VOID

+EFIAPI

+GicV3IrqInterruptHandler (

+  IN EFI_EXCEPTION_TYPE           InterruptType,

+  IN EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  UINT32                      GicInterrupt;

+  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;

+

+  GicInterrupt = ArmGicV3AcknowledgeInterrupt ();

+

+  // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the

+  // number of interrupt (ie: Spurious interrupt).

+  if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {

+    // The special interrupt do not need to be acknowledge

+    return;

+  }

+

+  InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];

+  if (InterruptHandler != NULL) {

+    // Call the registered interrupt handler.

+    InterruptHandler (GicInterrupt, SystemContext);

+  } else {

+    DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));

+  }

+

+  GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);

+}

+

+//

+// The protocol instance produced by this driver

+//

+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = {

+  RegisterInterruptSource,

+  GicV3EnableInterruptSource,

+  GicV3DisableInterruptSource,

+  GicV3GetInterruptSourceState,

+  GicV3EndOfInterrupt

+};

+

+/**

+  Shutdown our hardware

+

+  DXE Core will disable interrupts and turn off the timer and disable interrupts

+  after all the event handlers have run.

+

+  @param[in]  Event   The Event that is being processed

+  @param[in]  Context Event Context

+**/

+VOID

+EFIAPI

+GicV3ExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  UINTN    Index;

+

+  // Acknowledge all pending interrupts

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

+    GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);

+  }

+

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

+    GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, Index);

+  }

+

+  // Disable Gic Interface

+  ArmGicV3DisableInterruptInterface ();

+

+  // Disable Gic Distributor

+  ArmGicDisableDistributor (mGicDistributorBase);

+}

+

+/**

+  Initialize the state information for the CPU Architectural Protocol

+

+  @param  ImageHandle   of the loaded driver

+  @param  SystemTable   Pointer to the System Table

+

+  @retval EFI_SUCCESS           Protocol registered

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Hardware problems

+

+**/

+EFI_STATUS

+GicV3DxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+  UINTN                   Index;

+  UINT32                  RegOffset;

+  UINTN                   RegShift;

+  UINT64                  CpuTarget;

+  UINT64                  MpId;

+

+  // Make sure the Interrupt Controller Protocol is not already installed in the system.

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);

+

+  mGicDistributorBase    = PcdGet32 (PcdGicDistributorBase);

+  mGicRedistributorsBase = PcdGet32 (PcdGicRedistributorsBase);

+  mGicNumInterrupts      = ArmGicGetMaxNumInterrupts (mGicDistributorBase);

+

+  //

+  // We will be driving this GIC in native v3 mode, i.e., with Affinity

+  // Routing enabled. So ensure that the ARE bit is set.

+  //

+  if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {

+    MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE);

+  }

+

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

+    GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);

+

+    // Set Priority

+    RegOffset = Index / 4;

+    RegShift = (Index % 4) * 8;

+    MmioAndThenOr32 (

+      mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),

+      ~(0xff << RegShift),

+      ARM_GIC_DEFAULT_PRIORITY << RegShift

+      );

+  }

+

+  //

+  // Targets the interrupts to the Primary Cpu

+  //

+

+  MpId = ArmReadMpidr ();

+  CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);

+

+  // Route the SPIs to the primary CPU. SPIs start at the INTID 32

+  for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {

+    MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);

+  }

+

+  // Set binary point reg to 0x7 (no preemption)

+  ArmGicV3SetBinaryPointer (0x7);

+

+  // Set priority mask reg to 0xff to allow all priorities through

+  ArmGicV3SetPriorityMask (0xff);

+

+  // Enable gic cpu interface

+  ArmGicV3EnableInterruptInterface ();

+

+  // Enable gic distributor

+  ArmGicEnableDistributor (mGicDistributorBase);

+

+  Status = InstallAndRegisterInterruptService (

+          &gHardwareInterruptV3Protocol, GicV3IrqInterruptHandler, GicV3ExitBootServicesEvent);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
new file mode 100644
index 0000000..794e878
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
@@ -0,0 +1,68 @@
+/** @file

+*

+*  Copyright (c) 2014-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_GIC_V3_H_

+#define _ARM_GIC_V3_H_

+

+#define ICC_SRE_EL2_SRE         (1 << 0)

+

+#define ARM_GICD_IROUTER_IRM BIT31

+

+UINT32

+EFIAPI

+ArmGicV3GetControlSystemRegisterEnable (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGicV3SetControlSystemRegisterEnable (

+  IN UINT32         ControlSystemRegisterEnable

+  );

+

+VOID

+EFIAPI

+ArmGicV3EnableInterruptInterface (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGicV3DisableInterruptInterface (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmGicV3AcknowledgeInterrupt (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGicV3EndOfInterrupt (

+  IN UINTN                  Source

+  );

+

+VOID

+ArmGicV3SetBinaryPointer (

+  IN UINTN                  BinaryPoint

+  );

+

+VOID

+ArmGicV3SetPriorityMask (

+  IN UINTN                  Priority

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c
new file mode 100644
index 0000000..ce1c6ce
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c
@@ -0,0 +1,154 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Portions 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 "CpuDxe.h"

+

+#include <Chipset/AArch64.h>

+

+VOID

+ExceptionHandlersStart (

+  VOID

+  );

+

+VOID

+ExceptionHandlersEnd (

+  VOID

+  );

+

+VOID

+CommonExceptionEntry (

+  VOID

+  );

+

+VOID

+AsmCommonExceptionEntry (

+  VOID

+  );

+

+

+EFI_EXCEPTION_CALLBACK  gExceptionHandlers[MAX_AARCH64_EXCEPTION + 1];

+EFI_EXCEPTION_CALLBACK  gDebuggerExceptionHandlers[MAX_AARCH64_EXCEPTION + 1];

+

+

+

+/**

+  This function registers and enables the handler specified by InterruptHandler for a processor

+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the

+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.

+  The installed handler is called once for each processor interrupt or exception.

+

+  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts

+                           are enabled and FALSE if interrupts are disabled.

+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called

+                           when a processor interrupt occurs. If this parameter is NULL, then the handler

+                           will be uninstalled.

+

+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.

+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was

+                                previously installed.

+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not

+                                previously installed.

+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.

+

+**/

+EFI_STATUS

+RegisterInterruptHandler (

+  IN EFI_EXCEPTION_TYPE             InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler

+  )

+{

+  if (InterruptType > MAX_AARCH64_EXCEPTION) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  gExceptionHandlers[InterruptType] = InterruptHandler;

+

+  return EFI_SUCCESS;

+}

+

+

+

+VOID

+EFIAPI

+CommonCExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  if (ExceptionType <= MAX_AARCH64_EXCEPTION) {

+    if (gExceptionHandlers[ExceptionType]) {

+      gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);

+      return;

+    }

+  } else {

+    DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %016lx\n", ExceptionType, SystemContext.SystemContextAArch64->ELR));

+    ASSERT (FALSE);

+  }

+

+  DefaultExceptionHandler (ExceptionType, SystemContext);

+}

+

+

+

+EFI_STATUS

+InitializeExceptions (

+  IN EFI_CPU_ARCH_PROTOCOL    *Cpu

+  )

+{

+  EFI_STATUS           Status;

+  BOOLEAN              IrqEnabled;

+  BOOLEAN              FiqEnabled;

+

+  Status = EFI_SUCCESS;

+  ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));

+

+  //

+  // Disable interrupts

+  //

+  Cpu->GetInterruptState (Cpu, &IrqEnabled);

+  Cpu->DisableInterrupt (Cpu);

+

+  //

+  // EFI does not use the FIQ, but a debugger might so we must disable

+  // as we take over the exception vectors.

+  //

+  FiqEnabled = ArmGetFiqState ();

+  ArmDisableFiq ();

+

+  // The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure 'Align=4K'

+  // is defined into your FDF for this module.

+  ASSERT (((UINTN)ExceptionHandlersStart & ARM_VECTOR_TABLE_ALIGNMENT) == 0);

+

+  // We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector

+  // Base Address to point into CpuDxe code.

+  ArmWriteVBar ((UINTN)ExceptionHandlersStart);

+

+  if (FiqEnabled) {

+    ArmEnableFiq ();

+  }

+

+  if (IrqEnabled) {

+    //

+    // Restore interrupt state

+    //

+    Status = Cpu->EnableInterrupt (Cpu);

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
new file mode 100644
index 0000000..2682f4f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
@@ -0,0 +1,394 @@
+//

+// Copyright (c) 2011 - 2014 ARM LTD. All rights reserved.<BR>

+// Portion of Copyright (c) 2014 NVIDIA Corporation. 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/PcdLib.h>

+#include <AsmMacroIoLibV8.h>

+

+/*

+  This is the stack constructed by the exception handler (low address to high address).

+  X0 to FAR makes up the EFI_SYSTEM_CONTEXT for AArch64.

+

+  UINT64  X0;     0x000

+  UINT64  X1;     0x008

+  UINT64  X2;     0x010

+  UINT64  X3;     0x018

+  UINT64  X4;     0x020

+  UINT64  X5;     0x028

+  UINT64  X6;     0x030

+  UINT64  X7;     0x038

+  UINT64  X8;     0x040

+  UINT64  X9;     0x048

+  UINT64  X10;    0x050

+  UINT64  X11;    0x058

+  UINT64  X12;    0x060

+  UINT64  X13;    0x068

+  UINT64  X14;    0x070

+  UINT64  X15;    0x078

+  UINT64  X16;    0x080

+  UINT64  X17;    0x088

+  UINT64  X18;    0x090

+  UINT64  X19;    0x098

+  UINT64  X20;    0x0a0

+  UINT64  X21;    0x0a8

+  UINT64  X22;    0x0b0

+  UINT64  X23;    0x0b8

+  UINT64  X24;    0x0c0

+  UINT64  X25;    0x0c8

+  UINT64  X26;    0x0d0

+  UINT64  X27;    0x0d8

+  UINT64  X28;    0x0e0

+  UINT64  FP;     0x0e8   // x29 - Frame Pointer

+  UINT64  LR;     0x0f0   // x30 - Link Register

+  UINT64  SP;     0x0f8   // x31 - Stack Pointer

+

+  // FP/SIMD Registers. 128bit if used as Q-regs.

+  UINT64  V0[2];  0x100

+  UINT64  V1[2];  0x110

+  UINT64  V2[2];  0x120

+  UINT64  V3[2];  0x130

+  UINT64  V4[2];  0x140

+  UINT64  V5[2];  0x150

+  UINT64  V6[2];  0x160

+  UINT64  V7[2];  0x170

+  UINT64  V8[2];  0x180

+  UINT64  V9[2];  0x190

+  UINT64  V10[2]; 0x1a0

+  UINT64  V11[2]; 0x1b0

+  UINT64  V12[2]; 0x1c0

+  UINT64  V13[2]; 0x1d0

+  UINT64  V14[2]; 0x1e0

+  UINT64  V15[2]; 0x1f0

+  UINT64  V16[2]; 0x200

+  UINT64  V17[2]; 0x210

+  UINT64  V18[2]; 0x220

+  UINT64  V19[2]; 0x230

+  UINT64  V20[2]; 0x240

+  UINT64  V21[2]; 0x250

+  UINT64  V22[2]; 0x260

+  UINT64  V23[2]; 0x270

+  UINT64  V24[2]; 0x280

+  UINT64  V25[2]; 0x290

+  UINT64  V26[2]; 0x2a0

+  UINT64  V27[2]; 0x2b0

+  UINT64  V28[2]; 0x2c0

+  UINT64  V29[2]; 0x2d0

+  UINT64  V30[2]; 0x2e0

+  UINT64  V31[2]; 0x2f0

+

+  // System Context

+  UINT64  ELR;    0x300   // Exception Link Register

+  UINT64  SPSR;   0x308   // Saved Processor Status Register

+  UINT64  FPSR;   0x310   // Floating Point Status Register

+  UINT64  ESR;    0x318   // Exception syndrome register

+  UINT64  FAR;    0x320   // Fault Address Register

+  UINT64  Padding;0x328   // Required for stack alignment

+*/

+

+GCC_ASM_EXPORT(ExceptionHandlersStart)

+GCC_ASM_EXPORT(ExceptionHandlersEnd)

+GCC_ASM_EXPORT(CommonExceptionEntry)

+GCC_ASM_EXPORT(AsmCommonExceptionEntry)

+GCC_ASM_EXPORT(CommonCExceptionHandler)

+

+.text

+.align 11

+

+#define GP_CONTEXT_SIZE    (32 *  8)

+#define FP_CONTEXT_SIZE    (32 * 16)

+#define SYS_CONTEXT_SIZE   ( 6 *  8) // 5 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)

+

+// Cannot str x31 directly

+#define ALL_GP_REGS                                     \

+        REG_PAIR (x0,  x1,  0x000, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x2,  x3,  0x010, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x4,  x5,  0x020, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x6,  x7,  0x030, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x8,  x9,  0x040, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x10, x11, 0x050, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x12, x13, 0x060, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x14, x15, 0x070, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x16, x17, 0x080, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x18, x19, 0x090, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x20, x21, 0x0a0, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x22, x23, 0x0b0, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x24, x25, 0x0c0, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x26, x27, 0x0d0, GP_CONTEXT_SIZE);    \

+        REG_PAIR (x28, x29, 0x0e0, GP_CONTEXT_SIZE);    \

+        REG_ONE  (x30,      0x0f0, GP_CONTEXT_SIZE);

+

+// In order to save the SP we need to put it somewhere else first.

+// STR only works with XZR/WZR directly

+#define SAVE_SP \

+        add x1, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE); \

+        REG_ONE (x1,        0x0f8, GP_CONTEXT_SIZE);

+

+#define ALL_FP_REGS                                     \

+        REG_PAIR (q0,  q1,  0x000, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q2,  q3,  0x020, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q4,  q5,  0x040, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q6,  q7,  0x060, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q8,  q9,  0x080, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q10, q11, 0x0a0, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q12, q13, 0x0c0, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q14, q15, 0x0e0, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q16, q17, 0x100, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q18, q19, 0x120, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q20, q21, 0x140, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q22, q23, 0x160, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q24, q25, 0x180, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q26, q27, 0x1a0, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q28, q29, 0x1c0, FP_CONTEXT_SIZE);    \

+        REG_PAIR (q30, q31, 0x1e0, FP_CONTEXT_SIZE);

+

+#define ALL_SYS_REGS                                    \

+        REG_PAIR (x1,  x2,  0x000, SYS_CONTEXT_SIZE);   \

+        REG_PAIR (x3,  x4,  0x010, SYS_CONTEXT_SIZE);   \

+        REG_ONE  (x5,       0x020, SYS_CONTEXT_SIZE);

+

+//

+// This code gets copied to the ARM vector table

+// VectorTableStart - VectorTableEnd gets copied

+//

+ASM_PFX(ExceptionHandlersStart):

+

+//

+// Current EL with SP0 : 0x0 - 0x180

+//

+.align 7

+ASM_PFX(SynchronousExceptionSP0):

+  b   ASM_PFX(SynchronousExceptionEntry)

+

+.align 7

+ASM_PFX(IrqSP0):

+  b   ASM_PFX(IrqEntry)

+

+.align 7

+ASM_PFX(FiqSP0):

+  b   ASM_PFX(FiqEntry)

+

+.align 7

+ASM_PFX(SErrorSP0):

+  b   ASM_PFX(SErrorEntry)

+

+//

+// Current EL with SPx: 0x200 - 0x380

+//

+.align 7

+ASM_PFX(SynchronousExceptionSPx):

+  b   ASM_PFX(SynchronousExceptionEntry)

+

+.align 7

+ASM_PFX(IrqSPx):

+  b   ASM_PFX(IrqEntry)

+

+.align 7

+ASM_PFX(FiqSPx):

+  b   ASM_PFX(FiqEntry)

+

+.align 7

+ASM_PFX(SErrorSPx):

+  b   ASM_PFX(SErrorEntry)

+

+//

+// Lower EL using AArch64 : 0x400 - 0x580

+//

+.align 7

+ASM_PFX(SynchronousExceptionA64):

+  b   ASM_PFX(SynchronousExceptionEntry)

+

+.align 7

+ASM_PFX(IrqA64):

+  b   ASM_PFX(IrqEntry)

+

+.align 7

+ASM_PFX(FiqA64):

+  b   ASM_PFX(FiqEntry)

+

+.align 7

+ASM_PFX(SErrorA64):

+  b   ASM_PFX(SErrorEntry)

+

+//

+// Lower EL using AArch32 : 0x0 - 0x180

+//

+.align 7

+ASM_PFX(SynchronousExceptionA32):

+  b   ASM_PFX(SynchronousExceptionEntry)

+

+.align 7

+ASM_PFX(IrqA32):

+  b   ASM_PFX(IrqEntry)

+

+.align 7

+ASM_PFX(FiqA32):

+  b   ASM_PFX(FiqEntry)

+

+.align 7

+ASM_PFX(SErrorA32):

+  b   ASM_PFX(SErrorEntry)

+

+

+#undef  REG_PAIR

+#undef  REG_ONE

+#define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE)  stp  REG1, REG2, [sp, #(OFFSET-CONTEXT_SIZE)]

+#define REG_ONE(REG1, OFFSET, CONTEXT_SIZE)         stur REG1, [sp, #(OFFSET-CONTEXT_SIZE)]

+

+ASM_PFX(SynchronousExceptionEntry):

+  // Move the stackpointer so we can reach our structure with the str instruction.

+  sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+

+  // Save all the General regs before touching x0 and x1.

+  // This does not save r31(SP) as it is special. We do that later.

+  ALL_GP_REGS

+

+  // Record the type of exception that occurred.

+  mov       x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS

+

+  // Jump to our general handler to deal with all the common parts and process the exception.

+  ldr       x1, ASM_PFX(CommonExceptionEntry)

+  br        x1

+

+ASM_PFX(IrqEntry):

+  sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+  ALL_GP_REGS

+  mov       x0, #EXCEPT_AARCH64_IRQ

+  ldr       x1, ASM_PFX(CommonExceptionEntry)

+  br        x1

+

+ASM_PFX(FiqEntry):

+  sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+  ALL_GP_REGS

+  mov       x0, #EXCEPT_AARCH64_FIQ

+  ldr       x1, ASM_PFX(CommonExceptionEntry)

+  br        x1

+

+ASM_PFX(SErrorEntry):

+  sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+  ALL_GP_REGS

+  mov       x0, #EXCEPT_AARCH64_SERROR

+  ldr       x1, ASM_PFX(CommonExceptionEntry)

+  br        x1

+

+

+//

+// This gets patched by the C code that patches in the vector table

+//

+.align 3

+ASM_PFX(CommonExceptionEntry):

+  .8byte ASM_PFX(AsmCommonExceptionEntry)

+

+ASM_PFX(ExceptionHandlersEnd):

+

+

+

+//

+// This code runs from CpuDxe driver loaded address. It is patched into

+// CommonExceptionEntry.

+//

+ASM_PFX(AsmCommonExceptionEntry):

+  /* NOTE:

+     We have to break up the save code because the immediate value to be used

+     with the SP is too big to do it all in one step so we need to shuffle the SP

+     along as we go. (we only have 9bits of immediate to work with) */

+

+  // Save the current Stack pointer before we start modifying it.

+  SAVE_SP

+

+  // Preserve the stack pointer we came in with before we modify it

+  EL1_OR_EL2(x1)

+1:mrs      x1, elr_el1   // Exception Link Register

+  mrs      x2, spsr_el1  // Saved Processor Status Register 32bit

+  mrs      x3, fpsr      // Floating point Status Register  32bit

+  mrs      x4, esr_el1   // EL1 Exception syndrome register 32bit

+  mrs      x5, far_el1   // EL1 Fault Address Register

+  b        3f

+

+2:mrs      x1, elr_el2   // Exception Link Register

+  mrs      x2, spsr_el2  // Saved Processor Status Register 32bit

+  mrs      x3, fpsr      // Floating point Status Register  32bit

+  mrs      x4, esr_el2   // EL2 Exception syndrome register 32bit

+  mrs      x5, far_el2   // EL2 Fault Address Register

+

+  // Adjust SP to save next set

+3:add      sp, sp, #FP_CONTEXT_SIZE

+

+  // Push FP regs to Stack.

+  ALL_FP_REGS

+

+  // Adjust SP to save next set

+  add      sp, sp, #SYS_CONTEXT_SIZE

+

+  // Save the SYS regs

+  ALL_SYS_REGS

+

+  // Point to top of struct after all regs saved

+  sub      sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+

+  // x0 still holds the exception type.

+  // Set x1 to point to the top of our struct on the Stack

+  mov      x1, sp

+

+// CommonCExceptionHandler (

+//   IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0

+//   IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1

+//   )

+

+  // Call the handler as defined above

+

+  // For now we spin in the handler if we received an abort of some kind.

+  // We do not try to recover.

+  bl       ASM_PFX(CommonCExceptionHandler) // Call exception handler

+

+

+// Defines for popping from stack

+

+#undef REG_PAIR

+#undef REG_ONE

+#define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE)    ldp  REG1, REG2, [sp, #(OFFSET-CONTEXT_SIZE)]

+#define REG_ONE(REG1, OFFSET, CONTEXT_SIZE)           ldur REG1, [sp, #(OFFSET-CONTEXT_SIZE)]

+

+  // Adjust SP to pop system registers

+  add     sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+  ALL_SYS_REGS

+

+  EL1_OR_EL2(x6)

+1:msr      elr_el1, x1   // Exception Link Register

+  msr      spsr_el1,x2   // Saved Processor Status Register 32bit

+  msr      fpsr, x3      // Floating point Status Register  32bit

+  msr      esr_el1, x4   // EL1 Exception syndrome register 32bit

+  msr      far_el1, x5   // EL1 Fault Address Register

+  b        3f

+2:msr      elr_el2, x1   // Exception Link Register

+  msr      spsr_el2,x2   // Saved Processor Status Register 32bit

+  msr      fpsr, x3      // Floating point Status Register  32bit

+  msr      esr_el2, x4   // EL2 Exception syndrome register 32bit

+  msr      far_el2, x5   // EL2 Fault Address Register

+

+3:// pop all regs and return from exception.

+  sub     sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)

+  ALL_GP_REGS

+

+  // Adjust SP to pop next set

+  add      sp, sp, #FP_CONTEXT_SIZE

+  // Pop FP regs to Stack.

+  ALL_FP_REGS

+

+  // Adjust SP to be where we started from when we came into the handler.

+  // The handler can not change the SP.

+  add      sp, sp, #SYS_CONTEXT_SIZE

+

+  eret

+

+#undef REG_PAIR

+#undef REG_ONE

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
new file mode 100644
index 0000000..6cba121
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -0,0 +1,341 @@
+/*++

+

+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>

+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+Portions copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>

+

+This program and the accompanying materials

+are licensed and made available under the terms and conditions of the BSD License

+which accompanies this distribution.  The full text of the license may be found at

+http://opensource.org/licenses/bsd-license.php

+

+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+

+--*/

+

+#include <Library/MemoryAllocationLib.h>

+#include "CpuDxe.h"

+

+#define TT_ATTR_INDX_INVALID    ((UINT32)~0)

+

+STATIC

+UINT64

+GetFirstPageAttribute (

+  IN UINT64  *FirstLevelTableAddress,

+  IN UINTN    TableLevel

+  )

+{

+  UINT64 FirstEntry;

+

+  // Get the first entry of the table

+  FirstEntry = *FirstLevelTableAddress;

+

+  if ((TableLevel != 3) && (FirstEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {

+    // Only valid for Levels 0, 1 and 2

+

+    // Get the attribute of the subsequent table

+    return GetFirstPageAttribute ((UINT64*)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1);

+  } else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) ||

+             ((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3)))

+  {

+    return FirstEntry & TT_ATTR_INDX_MASK;

+  } else {

+    return TT_ATTR_INDX_INVALID;

+  }

+}

+

+STATIC

+UINT64

+GetNextEntryAttribute (

+  IN     UINT64 *TableAddress,

+  IN     UINTN   EntryCount,

+  IN     UINTN   TableLevel,

+  IN     UINT64  BaseAddress,

+  IN OUT UINT32 *PrevEntryAttribute,

+  IN OUT UINT64 *StartGcdRegion

+  )

+{

+  UINTN                             Index;

+  UINT64                            Entry;

+  UINT32                            EntryAttribute;

+  UINT32                            EntryType;

+  EFI_STATUS                        Status;

+  UINTN                             NumberOfDescriptors;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMap;

+

+  // Get the memory space map from GCD

+  MemorySpaceMap = NULL;

+  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);

+  ASSERT_EFI_ERROR (Status);

+

+  // We cannot get more than 3-level page table

+  ASSERT (TableLevel <= 3);

+

+  // While the top level table might not contain TT_ENTRY_COUNT entries;

+  // the subsequent ones should be filled up

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

+    Entry = TableAddress[Index];

+    EntryType = Entry & TT_TYPE_MASK;

+    EntryAttribute = Entry  & TT_ATTR_INDX_MASK;

+

+    // If Entry is a Table Descriptor type entry then go through the sub-level table

+    if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||

+        ((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {

+      if ((*PrevEntryAttribute == TT_ATTR_INDX_INVALID) || (EntryAttribute != *PrevEntryAttribute)) {

+        if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {

+          // Update GCD with the last region

+          SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,

+              *StartGcdRegion,

+              (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,

+              PageAttributeToGcdAttribute (*PrevEntryAttribute));

+        }

+

+        // Start of the new region

+        *StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));

+        *PrevEntryAttribute = EntryAttribute;

+      } else {

+        continue;

+      }

+    } else if (EntryType == TT_TYPE_TABLE_ENTRY) {

+      // Table Entry type is only valid for Level 0, 1, 2

+      ASSERT (TableLevel < 3);

+

+      // Increase the level number and scan the sub-level table

+      GetNextEntryAttribute ((UINT64*)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE),

+                             TT_ENTRY_COUNT, TableLevel + 1,

+                             (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),

+                             PrevEntryAttribute, StartGcdRegion);

+    } else {

+      if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {

+        // Update GCD with the last region

+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,

+            *StartGcdRegion,

+            (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,

+            PageAttributeToGcdAttribute (*PrevEntryAttribute));

+

+        // Start of the new region

+        *StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));

+        *PrevEntryAttribute = TT_ATTR_INDX_INVALID;

+      }

+    }

+  }

+

+  FreePool (MemorySpaceMap);

+

+  return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL(TableLevel));

+}

+

+EFI_STATUS

+SyncCacheConfig (

+  IN  EFI_CPU_ARCH_PROTOCOL *CpuProtocol

+  )

+{

+  EFI_STATUS                          Status;

+  UINT32                              PageAttribute = 0;

+  UINT64                             *FirstLevelTableAddress;

+  UINTN                               TableLevel;

+  UINTN                               TableCount;

+  UINTN                               NumberOfDescriptors;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap;

+  UINTN                               Tcr;

+  UINTN                               T0SZ;

+  UINT64                              BaseAddressGcdRegion;

+  UINT64                              EndAddressGcdRegion;

+

+  // This code assumes MMU is enabled and filed with section translations

+  ASSERT (ArmMmuEnabled ());

+

+  //

+  // Get the memory space map from GCD

+  //

+  MemorySpaceMap = NULL;

+  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);

+  ASSERT_EFI_ERROR (Status);

+

+  // The GCD implementation maintains its own copy of the state of memory space attributes.  GCD needs

+  // to know what the initial memory space attributes are.  The CPU Arch. Protocol does not provide a

+  // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were

+  // a client) to update its copy of the attributes.  This is bad architecture and should be replaced

+  // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.

+

+  // Obtain page table base

+  FirstLevelTableAddress = (UINT64*)(ArmGetTTBR0BaseAddress ());

+

+  // Get Translation Control Register value

+  Tcr = ArmGetTCR ();

+  // Get Address Region Size

+  T0SZ = Tcr & TCR_T0SZ_MASK;

+

+  // Get the level of the first table for the indicated Address Region Size

+  GetRootTranslationTableInfo (T0SZ, &TableLevel, &TableCount);

+

+  // First Attribute of the Page Tables

+  PageAttribute = GetFirstPageAttribute (FirstLevelTableAddress, TableLevel);

+

+  // We scan from the start of the memory map (ie: at the address 0x0)

+  BaseAddressGcdRegion = 0x0;

+  EndAddressGcdRegion = GetNextEntryAttribute (FirstLevelTableAddress,

+                                               TableCount, TableLevel,

+                                               BaseAddressGcdRegion,

+                                               &PageAttribute, &BaseAddressGcdRegion);

+

+  // Update GCD with the last region if valid

+  if (PageAttribute != TT_ATTR_INDX_INVALID) {

+    SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,

+        BaseAddressGcdRegion,

+        EndAddressGcdRegion - BaseAddressGcdRegion,

+        PageAttributeToGcdAttribute (PageAttribute));

+  }

+

+  FreePool (MemorySpaceMap);

+

+  return EFI_SUCCESS;

+}

+

+UINT64

+EfiAttributeToArmAttribute (

+  IN UINT64                    EfiAttributes

+  )

+{

+  UINT64 ArmAttributes;

+

+  switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {

+  case EFI_MEMORY_UC:

+    ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY;

+    break;

+  case EFI_MEMORY_WC:

+    ArmAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;

+    break;

+  case EFI_MEMORY_WT:

+    ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH;

+    break;

+  case EFI_MEMORY_WB:

+    ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK;

+    break;

+  default:

+    DEBUG ((EFI_D_ERROR, "EfiAttributeToArmAttribute: 0x%lX attributes is not supported.\n", EfiAttributes));

+    ASSERT (0);

+    ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY;

+  }

+

+  // Set the access flag to match the block attributes

+  ArmAttributes |= TT_AF;

+

+  // Determine protection attributes

+  if (EfiAttributes & EFI_MEMORY_WP) {

+    ArmAttributes |= TT_AP_RO_RO;

+  }

+

+  // Process eXecute Never attribute

+  if (EfiAttributes & EFI_MEMORY_XP) {

+    ArmAttributes |= TT_PXN_MASK;

+  }

+

+  return ArmAttributes;

+}

+

+// This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.

+// And then the function will identify the size of the region that has the same page table attribute.

+EFI_STATUS

+GetMemoryRegionRec (

+  IN     UINT64                  *TranslationTable,

+  IN     UINTN                    TableLevel,

+  IN     UINT64                  *LastBlockEntry,

+  IN OUT UINTN                   *BaseAddress,

+  OUT    UINTN                   *RegionLength,

+  OUT    UINTN                   *RegionAttributes

+  )

+{

+  EFI_STATUS Status;

+  UINT64    *NextTranslationTable;

+  UINT64    *BlockEntry;

+  UINT64     BlockEntryType;

+  UINT64     EntryType;

+

+  if (TableLevel != 3) {

+    BlockEntryType = TT_TYPE_BLOCK_ENTRY;

+  } else {

+    BlockEntryType = TT_TYPE_BLOCK_ENTRY_LEVEL3;

+  }

+

+  // Find the block entry linked to the Base Address

+  BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);

+  EntryType = *BlockEntry & TT_TYPE_MASK;

+

+  if ((TableLevel < 3) && (EntryType == TT_TYPE_TABLE_ENTRY)) {

+    NextTranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);

+

+    // The entry is a page table, so we go to the next level

+    Status = GetMemoryRegionRec (

+        NextTranslationTable, // Address of the next level page table

+        TableLevel + 1, // Next Page Table level

+        (UINTN*)TT_LAST_BLOCK_ADDRESS(NextTranslationTable, TT_ENTRY_COUNT),

+        BaseAddress, RegionLength, RegionAttributes);

+

+    // In case of 'Success', it means the end of the block region has been found into the upper

+    // level translation table

+    if (!EFI_ERROR(Status)) {

+      return EFI_SUCCESS;

+    }

+  } else if (EntryType == BlockEntryType) {

+    // We have found the BlockEntry attached to the address. We save its start address (the start

+    // address might be before the 'BaseAdress') and attributes

+    *BaseAddress      = *BaseAddress & ~(TT_ADDRESS_AT_LEVEL(TableLevel) - 1);

+    *RegionLength     = 0;

+    *RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK;

+  } else {

+    // We have an 'Invalid' entry

+    return EFI_UNSUPPORTED;

+  }

+

+  while (BlockEntry <= LastBlockEntry) {

+    if ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes) {

+      *RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL(TableLevel);

+    } else {

+      // In case we have found the end of the region we return success

+      return EFI_SUCCESS;

+    }

+    BlockEntry++;

+  }

+

+  // If we have reached the end of the TranslationTable and we have not found the end of the region then

+  // we return EFI_NOT_FOUND.

+  // The caller will continue to look for the memory region at its level

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+GetMemoryRegion (

+  IN OUT UINTN                   *BaseAddress,

+  OUT    UINTN                   *RegionLength,

+  OUT    UINTN                   *RegionAttributes

+  )

+{

+  EFI_STATUS  Status;

+  UINT64     *TranslationTable;

+  UINTN       TableLevel;

+  UINTN       EntryCount;

+  UINTN       T0SZ;

+

+  ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));

+

+  TranslationTable = ArmGetTTBR0BaseAddress ();

+

+  T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;

+  // Get the Table info from T0SZ

+  GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount);

+

+  Status = GetMemoryRegionRec (TranslationTable, TableLevel,

+      (UINTN*)TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount),

+      BaseAddress, RegionLength, RegionAttributes);

+

+  // If the region continues up to the end of the root table then GetMemoryRegionRec()

+  // will return EFI_NOT_FOUND

+  if (Status == EFI_NOT_FOUND) {

+    return EFI_SUCCESS;

+  } else {

+    return Status;

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.S b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.S
new file mode 100644
index 0000000..c82618a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.S
@@ -0,0 +1,191 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(ExceptionHandlersStart)

+GCC_ASM_EXPORT(ExceptionHandlersEnd)

+GCC_ASM_EXPORT(CommonExceptionEntry)

+GCC_ASM_EXPORT(AsmCommonExceptionEntry)

+GCC_ASM_EXPORT(CommonCExceptionHandler)

+

+ASM_PFX(ExceptionHandlersStart):

+

+ASM_PFX(Reset):

+  b ASM_PFX(ResetEntry)

+

+ASM_PFX(UndefinedInstruction):

+  b ASM_PFX(UndefinedInstructionEntry)

+

+ASM_PFX(SoftwareInterrupt):

+  b ASM_PFX(SoftwareInterruptEntry)

+

+ASM_PFX(PrefetchAbort):

+  b ASM_PFX(PrefetchAbortEntry)

+

+ASM_PFX(DataAbort):

+  b ASM_PFX(DataAbortEntry)

+

+ASM_PFX(ReservedException):

+  b ASM_PFX(ReservedExceptionEntry)

+

+ASM_PFX(Irq):

+  b ASM_PFX(IrqEntry)

+

+ASM_PFX(Fiq):

+  b ASM_PFX(FiqEntry)

+

+ASM_PFX(ResetEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#0

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(UndefinedInstructionEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#1

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(SoftwareInterruptEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#2

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(PrefetchAbortEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#3

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(DataAbortEntry):

+  sub       LR,LR,#8

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#4

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(ReservedExceptionEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#5

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(IrqEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#6

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(FiqEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       r0,#7

+  ldr       r1,ASM_PFX(CommonExceptionEntry)

+  bx        r1

+

+ASM_PFX(CommonExceptionEntry):

+  .byte       0x12

+  .byte       0x34

+  .byte       0x56

+  .byte       0x78

+

+ASM_PFX(ExceptionHandlersEnd):

+

+ASM_PFX(AsmCommonExceptionEntry):

+  mrc       p15, 0, R1, c6, c0, 2   @ Read IFAR

+  str       R1, [SP, #0x50]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR

+

+  mrc       p15, 0, R1, c5, c0, 1   @ Read IFSR

+  str       R1, [SP, #0x4c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR

+

+  mrc       p15, 0, R1, c6, c0, 0   @ Read DFAR

+  str       R1, [SP, #0x48]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR

+

+  mrc       p15, 0, R1, c5, c0, 0   @ Read DFSR

+  str       R1, [SP, #0x44]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

+

+  ldr       R1, [SP, #0x5c]         @ srsdb saved pre-exception CPSR on the stack

+  str       R1, [SP, #0x40]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

+  and       r1, r1, #0x1f           @ Check to see if User or System Mode

+  cmp       r1, #0x1f

+  cmpne     r1, #0x10

+  add       R2, SP, #0x38           @ Store it in EFI_SYSTEM_CONTEXT_ARM.LR

+  ldmneed   r2, {lr}^               @ User or System mode, use unbanked register

+  ldmneed   r2, {lr}                @ All other modes used banked register

+

+  ldr       R1, [SP, #0x58]         @ PC is the LR pushed by srsdb

+  str       R1, [SP, #0x3c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC

+

+  sub       R1, SP, #0x60           @ We pused 0x60 bytes on the stack

+  str       R1, [SP, #0x34]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP

+

+                                              @ R0 is exception type

+  mov       R1,SP                             @ Prepare System Context pointer as an argument for the exception handler

+  blx       ASM_PFX(CommonCExceptionHandler)  @ Call exception handler

+

+  ldr       R2,[SP,#0x40]           @ EFI_SYSTEM_CONTEXT_ARM.CPSR

+  str       R2,[SP,#0x5c]           @ Store it back to srsdb stack slot so it can be restored

+

+  ldr       R2,[SP,#0x3c]           @ EFI_SYSTEM_CONTEXT_ARM.PC

+  str       R2,[SP,#0x58]           @ Store it back to srsdb stack slot so it can be restored

+

+  ldmfd     SP!,{R0-R12}            @ Restore general purpose registers

+                                    @ Exception handler can not change SP or LR as we would blow chunks

+

+  add       SP,SP,#0x20             @ Clear out the remaining stack space

+  ldmfd     SP!,{LR}                @ restore the link register for this context

+  rfefd     SP!                     @ return from exception via srsdb stack slot

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.asm b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.asm
new file mode 100644
index 0000000..9f09a0b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.asm
@@ -0,0 +1,152 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+  EXPORT  ExceptionHandlersStart

+  EXPORT  ExceptionHandlersEnd

+  EXPORT  CommonExceptionEntry

+  EXPORT  AsmCommonExceptionEntry

+  IMPORT  CommonCExceptionHandler

+

+  PRESERVE8

+  AREA  DxeExceptionHandlers, CODE, READONLY

+

+ExceptionHandlersStart

+

+Reset

+  b   ResetEntry

+

+UndefinedInstruction

+  b   UndefinedInstructionEntry

+

+SoftwareInterrupt

+  b   SoftwareInterruptEntry

+

+PrefetchAbort

+  b   PrefetchAbortEntry

+

+DataAbort

+  b   DataAbortEntry

+

+ReservedException

+  b   ReservedExceptionEntry

+

+Irq

+  b   IrqEntry

+

+Fiq

+  b   FiqEntry

+

+ResetEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#0

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+UndefinedInstructionEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#1

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+SoftwareInterruptEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#2

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+PrefetchAbortEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#3

+  SUB       LR,LR,#4

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+DataAbortEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#4

+  SUB       LR,LR,#8

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+ReservedExceptionEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#5

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+IrqEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#6

+  SUB       LR,LR,#4

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+FiqEntry

+  stmfd     SP!,{R0-R1}

+  mov       R0,#7

+  SUB       LR,LR,#4

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+CommonExceptionEntry

+  dcd       0x12345678

+

+ExceptionHandlersEnd

+

+AsmCommonExceptionEntry

+  mrc       p15, 0, r1, c6, c0, 2   ; Read IFAR

+  stmfd     SP!,{R1}                ; Store the IFAR

+

+  mrc       p15, 0, r1, c5, c0, 1   ; Read IFSR

+  stmfd     SP!,{R1}                ; Store the IFSR

+

+  mrc       p15, 0, r1, c6, c0, 0   ; Read DFAR

+  stmfd     SP!,{R1}                ; Store the DFAR

+

+  mrc       p15, 0, r1, c5, c0, 0   ; Read DFSR

+  stmfd     SP!,{R1}                ; Store the DFSR

+

+  mrs       R1,SPSR                 ; Read SPSR (which is the pre-exception CPSR)

+  stmfd     SP!,{R1}                ; Store the SPSR

+

+  stmfd     SP!,{LR}                ; Store the link register (which is the pre-exception PC)

+  stmfd     SP,{SP,LR}^             ; Store user/system mode stack pointer and link register

+  nop                               ; Required by ARM architecture

+  SUB       SP,SP,#0x08             ; Adjust stack pointer

+  stmfd     SP!,{R2-R12}            ; Store general purpose registers

+

+  ldr       R3,[SP,#0x50]           ; Read saved R1 from the stack (it was saved by the exception entry routine)

+  ldr       R2,[SP,#0x4C]           ; Read saved R0 from the stack (it was saved by the exception entry routine)

+  stmfd     SP!,{R2-R3}             ; Store general purpose registers R0 and R1

+

+  mov       R1,SP                   ; Prepare System Context pointer as an argument for the exception handler

+

+  sub       SP,SP,#4                ; Adjust SP to preserve 8-byte alignment

+  blx       CommonCExceptionHandler ; Call exception handler

+  add       SP,SP,#4                ; Adjust SP back to where we were

+

+  ldr       R2,[SP,#0x40]           ; Load CPSR from context, in case it has changed

+  MSR       SPSR_cxsf,R2            ; Store it back to the SPSR to be restored when exiting this handler

+

+  ldmfd     SP!,{R0-R12}            ; Restore general purpose registers

+  ldm       SP,{SP,LR}^             ; Restore user/system mode stack pointer and link register

+  nop                               ; Required by ARM architecture

+  add       SP,SP,#0x08             ; Adjust stack pointer

+  ldmfd     SP!,{LR}                ; Restore the link register (which is the pre-exception PC)

+  add       SP,SP,#0x1C             ; Clear out the remaining stack space

+  movs      PC,LR                   ; Return from exception

+

+  END

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c
new file mode 100644
index 0000000..4b05199
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c
@@ -0,0 +1,234 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2014, ARM Limited. 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 "CpuDxe.h"

+

+//FIXME: Will not compile on non-ARMv7 builds

+#include <Chipset/ArmV7.h>

+

+VOID

+ExceptionHandlersStart (

+  VOID

+  );

+

+VOID

+ExceptionHandlersEnd (

+  VOID

+  );

+

+VOID

+CommonExceptionEntry (

+  VOID

+  );

+

+VOID

+AsmCommonExceptionEntry (

+  VOID

+  );

+

+

+EFI_EXCEPTION_CALLBACK  gExceptionHandlers[MAX_ARM_EXCEPTION + 1];

+EFI_EXCEPTION_CALLBACK  gDebuggerExceptionHandlers[MAX_ARM_EXCEPTION + 1];

+

+

+

+/**

+  This function registers and enables the handler specified by InterruptHandler for a processor

+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the

+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.

+  The installed handler is called once for each processor interrupt or exception.

+

+  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts

+                           are enabled and FALSE if interrupts are disabled.

+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called

+                           when a processor interrupt occurs. If this parameter is NULL, then the handler

+                           will be uninstalled.

+

+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.

+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was

+                                previously installed.

+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not

+                                previously installed.

+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.

+

+**/

+EFI_STATUS

+RegisterInterruptHandler (

+  IN EFI_EXCEPTION_TYPE             InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler

+  )

+{

+  if (InterruptType > MAX_ARM_EXCEPTION) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  gExceptionHandlers[InterruptType] = InterruptHandler;

+

+  return EFI_SUCCESS;

+}

+

+

+

+

+VOID

+EFIAPI

+CommonCExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  if (ExceptionType <= MAX_ARM_EXCEPTION) {

+    if (gExceptionHandlers[ExceptionType]) {

+      gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);

+      return;

+    }

+  } else {

+    DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %08x\n", ExceptionType, SystemContext.SystemContextArm->PC));

+    ASSERT (FALSE);

+  }

+

+  if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {

+    //

+    // ARM JTAG debuggers some times use this vector, so it is not an error to get one

+    //

+    return;

+  }

+

+  DefaultExceptionHandler (ExceptionType, SystemContext);

+}

+

+

+

+EFI_STATUS

+InitializeExceptions (

+  IN EFI_CPU_ARCH_PROTOCOL    *Cpu

+  )

+{

+  EFI_STATUS           Status;

+  UINTN                Offset;

+  UINTN                Length;

+  UINTN                Index;

+  BOOLEAN              IrqEnabled;

+  BOOLEAN              FiqEnabled;

+  EFI_PHYSICAL_ADDRESS Base;

+  UINT32               *VectorBase;

+

+  Status = EFI_SUCCESS;

+  ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));

+

+  //

+  // Disable interrupts

+  //

+  Cpu->GetInterruptState (Cpu, &IrqEnabled);

+  Cpu->DisableInterrupt (Cpu);

+

+  //

+  // EFI does not use the FIQ, but a debugger might so we must disable

+  // as we take over the exception vectors.

+  //

+  FiqEnabled = ArmGetFiqState ();

+  ArmDisableFiq ();

+

+  if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) {

+    //

+    // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.

+    //

+    Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;

+

+    // Check if the exception vector is in the low address

+    if (PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) {

+      // Set SCTLR.V to 0 to enable VBAR to be used

+      ArmSetLowVectors ();

+    } else {

+      ArmSetHighVectors ();

+    }

+

+    //

+    // Reserve space for the exception handlers

+    //

+    Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);

+    VectorBase = (UINT32 *)(UINTN)Base;

+    Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);

+    // If the request was for memory that's not in the memory map (which is often the case for 0x00000000

+    // on embedded systems, for example, we don't want to hang up.  So we'll check here for a status of

+    // EFI_NOT_FOUND, and continue in that case.

+    if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {

+      ASSERT_EFI_ERROR (Status);

+    }

+

+    if (FeaturePcdGet(PcdDebuggerExceptionSupport) == TRUE) {

+      // Save existing vector table, in case debugger is already hooked in

+      CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));

+    }

+

+    // Copy our assembly code into the page that contains the exception vectors.

+    CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);

+

+    //

+    // Patch in the common Assembly exception handler

+    //

+    Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;

+    *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;

+

+    //

+    // Initialize the C entry points for interrupts

+    //

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

+      if (!FeaturePcdGet(PcdDebuggerExceptionSupport) ||

+          (gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {

+        // Exception handler contains branch to vector location (jmp $) so no handler

+        // NOTE: This code assumes vectors are ARM and not Thumb code

+        Status = RegisterInterruptHandler (Index, NULL);

+        ASSERT_EFI_ERROR (Status);

+      } else {

+        // If the debugger has already hooked put its vector back

+        VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];

+      }

+    }

+

+    // Flush Caches since we updated executable stuff

+    InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);

+

+    //Note: On ARM processor with the Security Extension, the Vector Table can be located anywhere in the memory.

+    //      The Vector Base Address Register defines the location

+    ArmWriteVBar (PcdGet32(PcdCpuVectorBaseAddress));

+  } else {

+    // The Vector table must be 32-byte aligned

+    if (((UINT32)ExceptionHandlersStart & ARM_VECTOR_TABLE_ALIGNMENT) != 0) {

+      ASSERT (0);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    // We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector Base Address to point into CpuDxe code.

+    ArmWriteVBar ((UINT32)ExceptionHandlersStart);

+  }

+

+  if (FiqEnabled) {

+    ArmEnableFiq ();

+  }

+

+  if (IrqEnabled) {

+    //

+    // Restore interrupt state

+    //

+    Status = Cpu->EnableInterrupt (Cpu);

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
new file mode 100644
index 0000000..3433b99
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
@@ -0,0 +1,303 @@
+#------------------------------------------------------------------------------

+#

+# Use ARMv6 instruction to operate on a single stack

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# Copyright (c) 2014, ARM Limited. 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/PcdLib.h>

+

+/*

+

+This is the stack constructed by the exception handler (low address to high address)

+                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM

+  Reg   Offset

+  ===   ======

+  R0    0x00    # stmfd     SP!,{R0-R12}

+  R1    0x04

+  R2    0x08

+  R3    0x0c

+  R4    0x10

+  R5    0x14

+  R6    0x18

+  R7    0x1c

+  R8    0x20

+  R9    0x24

+  R10   0x28

+  R11   0x2c

+  R12   0x30

+  SP    0x34    # reserved via subtraction 0x20 (32) from SP

+  LR    0x38

+  PC    0x3c

+  CPSR  0x40

+  DFSR  0x44

+  DFAR  0x48

+  IFSR  0x4c

+  IFAR  0x50

+

+  LR    0x54    # SVC Link register (we need to restore it)

+

+  LR    0x58    # pushed by srsfd

+  CPSR  0x5c

+

+ */

+

+

+GCC_ASM_EXPORT(ExceptionHandlersStart)

+GCC_ASM_EXPORT(ExceptionHandlersEnd)

+GCC_ASM_EXPORT(CommonExceptionEntry)

+GCC_ASM_EXPORT(AsmCommonExceptionEntry)

+GCC_ASM_EXPORT(CommonCExceptionHandler)

+

+.text

+#if !defined(__APPLE__)

+.fpu neon    @ makes vpush/vpop assemble

+#endif

+.align 5

+

+

+//

+// This code gets copied to the ARM vector table

+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied

+//

+ASM_PFX(ExceptionHandlersStart):

+

+ASM_PFX(Reset):

+  b ASM_PFX(ResetEntry)

+

+ASM_PFX(UndefinedInstruction):

+  b ASM_PFX(UndefinedInstructionEntry)

+

+ASM_PFX(SoftwareInterrupt):

+  b ASM_PFX(SoftwareInterruptEntry)

+

+ASM_PFX(PrefetchAbort):

+  b ASM_PFX(PrefetchAbortEntry)

+

+ASM_PFX(DataAbort):

+  b ASM_PFX(DataAbortEntry)

+

+ASM_PFX(ReservedException):

+  b ASM_PFX(ReservedExceptionEntry)

+

+ASM_PFX(Irq):

+  b ASM_PFX(IrqEntry)

+

+ASM_PFX(Fiq):

+  b ASM_PFX(FiqEntry)

+

+ASM_PFX(ResetEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+                                      @ We are already in SVC mode

+

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#0                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(UndefinedInstructionEntry):

+  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#1                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(SoftwareInterruptEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+                                      @ We are already in SVC mode

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#2                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(PrefetchAbortEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#3                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(DataAbortEntry):

+  sub       LR,LR,#8

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#4

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(ReservedExceptionEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#5

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(IrqEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#6                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(FiqEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+                                      @ Since we have already switch to SVC R8_fiq - R12_fiq

+                                      @ never get used or saved

+  mov       R0,#7                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+//

+// This gets patched by the C code that patches in the vector table

+//

+ASM_PFX(CommonExceptionEntry):

+  .word       ASM_PFX(AsmCommonExceptionEntry)

+

+ASM_PFX(ExceptionHandlersEnd):

+

+//

+// This code runs from CpuDxe driver loaded address. It is patched into

+// CommonExceptionEntry.

+//

+ASM_PFX(AsmCommonExceptionEntry):

+  mrc       p15, 0, R1, c6, c0, 2   @ Read IFAR

+  str       R1, [SP, #0x50]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR

+

+  mrc       p15, 0, R1, c5, c0, 1   @ Read IFSR

+  str       R1, [SP, #0x4c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR

+

+  mrc       p15, 0, R1, c6, c0, 0   @ Read DFAR

+  str       R1, [SP, #0x48]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR

+

+  mrc       p15, 0, R1, c5, c0, 0   @ Read DFSR

+  str       R1, [SP, #0x44]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

+

+  ldr       R1, [SP, #0x5c]         @ srsdb saved pre-exception CPSR on the stack

+  str       R1, [SP, #0x40]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

+

+  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R3, R1, #0x1f           @ Check CPSR to see if User or System Mode

+  cmp       R3, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1f))

+  cmpne     R3, #0x10               @

+  stmeqed   R2, {lr}^               @   save unbanked lr

+                                    @ else

+  stmneed   R2, {lr}                @   save SVC lr

+

+

+  ldr       R5, [SP, #0x58]         @ PC is the LR pushed by srsfd

+                                    @ Check to see if we have to adjust for Thumb entry

+  sub       r4, r0, #1              @ if (ExceptionType == 1 || ExceptionType == 2)) {

+  cmp       r4, #1                  @   // UND & SVC have differnt LR adjust for Thumb

+  bhi       NoAdjustNeeded

+

+  tst       r1, #0x20               @   if ((CPSR & T)) == T) {  // Thumb Mode on entry

+  addne     R5, R5, #2              @     PC += 2;

+  strne     R5,[SP,#0x58]           @ Update LR value pushed by srsfd

+

+NoAdjustNeeded:

+

+  str       R5, [SP, #0x3c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC

+

+  add       R1, SP, #0x60           @ We pushed 0x60 bytes on the stack

+  str       R1, [SP, #0x34]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP

+

+                                    @ R0 is ExceptionType

+  mov       R1,SP                   @ R1 is SystemContext

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpush     {d0-d15}                @ save vstm registers in case they are used in optimizations

+#endif

+

+  mov       R4, SP                  @ Save current SP

+  tst       R4, #4

+  subne     SP, SP, #4              @ Adjust SP if not 8-byte aligned

+

+/*

+VOID

+EFIAPI

+CommonCExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1

+  )

+

+*/

+  blx       ASM_PFX(CommonCExceptionHandler)  @ Call exception handler

+

+  mov       SP, R4                  @ Restore SP

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpop      {d0-d15}

+#endif

+

+  ldr       R1, [SP, #0x4c]         @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR

+  mcr       p15, 0, R1, c5, c0, 1   @ Write IFSR

+

+  ldr       R1, [SP, #0x44]         @ Restore EFI_SYSTEM_CONTEXT_ARM.DFSR

+  mcr       p15, 0, R1, c5, c0, 0   @ Write DFSR

+

+  ldr       R1,[SP,#0x3c]           @ EFI_SYSTEM_CONTEXT_ARM.PC

+  str       R1,[SP,#0x58]           @ Store it back to srsfd stack slot so it can be restored

+

+  ldr       R1,[SP,#0x40]           @ EFI_SYSTEM_CONTEXT_ARM.CPSR

+  str       R1,[SP,#0x5c]           @ Store it back to srsfd stack slot so it can be restored

+

+  add       R3, SP, #0x54           @ Make R3 point to SVC LR saved on entry

+  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R1, R1, #0x1f           @ Check to see if User or System Mode

+  cmp       R1, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1f))

+  cmpne     R1, #0x10               @

+  ldmeqed   R2, {lr}^               @   restore unbanked lr

+                                    @ else

+  ldmneed   R3, {lr}                @   restore SVC lr, via ldmfd SP!, {LR}

+

+  ldmfd     SP!,{R0-R12}            @ Restore general purpose registers

+                                    @ Exception handler can not change SP

+

+  add       SP,SP,#0x20             @ Clear out the remaining stack space

+  ldmfd     SP!,{LR}                @ restore the link register for this context

+  rfefd     SP!                     @ return from exception via srsfd stack slot

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
new file mode 100644
index 0000000..b28ff9f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
@@ -0,0 +1,301 @@
+//------------------------------------------------------------------------------

+//

+// Use ARMv6 instruction to operate on a single stack

+//

+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+// Copyright (c) 2014, ARM Limited. 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/PcdLib.h>

+

+/*

+

+This is the stack constructed by the exception handler (low address to high address)

+                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM

+  Reg   Offset

+  ===   ======

+  R0    0x00    # stmfd     SP!,{R0-R12}

+  R1    0x04

+  R2    0x08

+  R3    0x0c

+  R4    0x10

+  R5    0x14

+  R6    0x18

+  R7    0x1c

+  R8    0x20

+  R9    0x24

+  R10   0x28

+  R11   0x2c

+  R12   0x30

+  SP    0x34    # reserved via subtraction 0x20 (32) from SP

+  LR    0x38

+  PC    0x3c

+  CPSR  0x40

+  DFSR  0x44

+  DFAR  0x48

+  IFSR  0x4c

+  IFAR  0x50

+

+  LR    0x54    # SVC Link register (we need to restore it)

+

+  LR    0x58    # pushed by srsfd

+  CPSR  0x5c

+

+ */

+

+

+  EXPORT  ExceptionHandlersStart

+  EXPORT  ExceptionHandlersEnd

+  EXPORT  CommonExceptionEntry

+  EXPORT  AsmCommonExceptionEntry

+  IMPORT  CommonCExceptionHandler

+

+  PRESERVE8

+  AREA  DxeExceptionHandlers, CODE, READONLY, CODEALIGN, ALIGN=5

+

+//

+// This code gets copied to the ARM vector table

+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied

+//

+ExceptionHandlersStart

+

+Reset

+  b   ResetEntry

+

+UndefinedInstruction

+  b   UndefinedInstructionEntry

+

+SoftwareInterrupt

+  b   SoftwareInterruptEntry

+

+PrefetchAbort

+  b   PrefetchAbortEntry

+

+DataAbort

+  b   DataAbortEntry

+

+ReservedException

+  b   ReservedExceptionEntry

+

+Irq

+  b   IrqEntry

+

+Fiq

+  b   FiqEntry

+

+ResetEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+                                      ; We are already in SVC mode

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#0                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+UndefinedInstructionEntry

+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#1                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry;

+  bx        R1

+

+SoftwareInterruptEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+                                      ; We are already in SVC mode

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#2                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+PrefetchAbortEntry

+  sub       LR,LR,#4

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#3                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+DataAbortEntry

+  sub       LR,LR,#8

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#4                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+ReservedExceptionEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#5                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+IrqEntry

+  sub       LR,LR,#4

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#6                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+FiqEntry

+  sub       LR,LR,#4

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+                                      ; Since we have already switch to SVC R8_fiq - R12_fiq

+                                      ; never get used or saved

+  mov       R0,#7                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+//

+// This gets patched by the C code that patches in the vector table

+//

+CommonExceptionEntry

+  dcd       AsmCommonExceptionEntry

+

+ExceptionHandlersEnd

+

+//

+// This code runs from CpuDxe driver loaded address. It is patched into

+// CommonExceptionEntry.

+//

+AsmCommonExceptionEntry

+  mrc       p15, 0, R1, c6, c0, 2   ; Read IFAR

+  str       R1, [SP, #0x50]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR

+

+  mrc       p15, 0, R1, c5, c0, 1   ; Read IFSR

+  str       R1, [SP, #0x4c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR

+

+  mrc       p15, 0, R1, c6, c0, 0   ; Read DFAR

+  str       R1, [SP, #0x48]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR

+

+  mrc       p15, 0, R1, c5, c0, 0   ; Read DFSR

+  str       R1, [SP, #0x44]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

+

+  ldr       R1, [SP, #0x5c]         ; srsfd saved pre-exception CPSR on the stack

+  str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

+

+  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R3, R1, #0x1f           ; Check CPSR to see if User or System Mode

+  cmp       R3, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1f))

+  cmpne     R3, #0x10               ;

+  stmeqed   R2, {lr}^               ;   save unbanked lr

+                                    ; else

+  stmneed   R2, {lr}                ;   save SVC lr

+

+

+  ldr       R5, [SP, #0x58]         ; PC is the LR pushed by srsfd

+                                    ; Check to see if we have to adjust for Thumb entry

+  sub       r4, r0, #1              ; if (ExceptionType == 1 || ExceptionType == 2)) {

+  cmp       r4, #1                  ;   // UND & SVC have differnt LR adjust for Thumb

+  bhi       NoAdjustNeeded

+

+  tst       r1, #0x20               ;   if ((CPSR & T)) == T) {  // Thumb Mode on entry

+  addne     R5, R5, #2              ;     PC += 2;

+  strne     R5,[SP,#0x58]           ; Update LR value pushed by srsfd

+

+NoAdjustNeeded

+

+  str       R5, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC

+

+  add       R1, SP, #0x60           ; We pushed 0x60 bytes on the stack

+  str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP

+

+                                    ; R0 is ExceptionType

+  mov       R1,SP                   ; R1 is SystemContext

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpush    {d0-d15}                 ; save vstm registers in case they are used in optimizations

+#endif

+

+  mov       R4, SP                  ; Save current SP

+  tst       R4, #4

+  subne     SP, SP, #4              ; Adjust SP if not 8-byte aligned

+

+/*

+VOID

+EFIAPI

+CommonCExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1

+  )

+

+*/

+  blx       CommonCExceptionHandler ; Call exception handler

+

+  mov       SP, R4                  ; Restore SP

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpop      {d0-d15}

+#endif

+

+  ldr       R1, [SP, #0x4c]         ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR

+  mcr       p15, 0, R1, c5, c0, 1   ; Write IFSR

+

+  ldr       R1, [SP, #0x44]         ; Restore EFI_SYSTEM_CONTEXT_ARM.DFSR

+  mcr       p15, 0, R1, c5, c0, 0   ; Write DFSR

+

+  ldr       R1,[SP,#0x3c]           ; EFI_SYSTEM_CONTEXT_ARM.PC

+  str       R1,[SP,#0x58]           ; Store it back to srsfd stack slot so it can be restored

+

+  ldr       R1,[SP,#0x40]           ; EFI_SYSTEM_CONTEXT_ARM.CPSR

+  str       R1,[SP,#0x5c]           ; Store it back to srsfd stack slot so it can be restored

+

+  add       R3, SP, #0x54           ; Make R3 point to SVC LR saved on entry

+  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R1, R1, #0x1f           ; Check to see if User or System Mode

+  cmp       R1, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1f))

+  cmpne     R1, #0x10               ;

+  ldmeqed   R2, {lr}^               ;   restore unbanked lr

+                                    ; else

+  ldmneed   R3, {lr}                ;   restore SVC lr, via ldmfd SP!, {LR}

+

+  ldmfd     SP!,{R0-R12}            ; Restore general purpose registers

+                                    ; Exception handler can not change SP

+

+  add       SP,SP,#0x20             ; Clear out the remaining stack space

+  ldmfd     SP!,{LR}                ; restore the link register for this context

+  rfefd     SP!                     ; return from exception via srsfd stack slot

+

+  END

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c
new file mode 100644
index 0000000..63da8ba
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c
@@ -0,0 +1,880 @@
+/*++

+

+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>

+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+Portions copyright (c) 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 <Library/MemoryAllocationLib.h>

+#include "CpuDxe.h"

+

+// First Level Descriptors

+typedef UINT32    ARM_FIRST_LEVEL_DESCRIPTOR;

+

+// Second Level Descriptors

+typedef UINT32    ARM_PAGE_TABLE_ENTRY;

+

+EFI_STATUS

+SectionToGcdAttributes (

+  IN  UINT32  SectionAttributes,

+  OUT UINT64  *GcdAttributes

+  )

+{

+  *GcdAttributes = 0;

+

+  // determine cacheability attributes

+  switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:

+      *GcdAttributes |= EFI_MEMORY_UC;

+      break;

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:

+      *GcdAttributes |= EFI_MEMORY_UC;

+      break;

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:

+      *GcdAttributes |= EFI_MEMORY_WT;

+      break;

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:

+      *GcdAttributes |= EFI_MEMORY_WB;

+      break;

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:

+      *GcdAttributes |= EFI_MEMORY_WC;

+      break;

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:

+      *GcdAttributes |= EFI_MEMORY_WB;

+      break;

+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE:

+      *GcdAttributes |= EFI_MEMORY_UC;

+      break;

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  // determine protection attributes

+  switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {

+    case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write

+      //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;

+      break;

+

+    case TT_DESCRIPTOR_SECTION_AP_RW_NO:

+    case TT_DESCRIPTOR_SECTION_AP_RW_RW:

+      // normal read/write access, do not add additional attributes

+      break;

+

+    // read only cases map to write-protect

+    case TT_DESCRIPTOR_SECTION_AP_RO_NO:

+    case TT_DESCRIPTOR_SECTION_AP_RO_RO:

+      *GcdAttributes |= EFI_MEMORY_WP;

+      break;

+

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  // now process eXectue Never attribute

+  if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {

+    *GcdAttributes |= EFI_MEMORY_XP;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+PageToGcdAttributes (

+  IN  UINT32  PageAttributes,

+  OUT UINT64  *GcdAttributes

+  )

+{

+  *GcdAttributes = 0;

+

+  // determine cacheability attributes

+  switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:

+      *GcdAttributes |= EFI_MEMORY_UC;

+      break;

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE:

+      *GcdAttributes |= EFI_MEMORY_UC;

+      break;

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:

+      *GcdAttributes |= EFI_MEMORY_WT;

+      break;

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC:

+      *GcdAttributes |= EFI_MEMORY_WB;

+      break;

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE:

+      *GcdAttributes |= EFI_MEMORY_WC;

+      break;

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC:

+      *GcdAttributes |= EFI_MEMORY_WB;

+      break;

+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE:

+      *GcdAttributes |= EFI_MEMORY_UC;

+      break;

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  // determine protection attributes

+  switch(PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {

+    case TT_DESCRIPTOR_PAGE_AP_NO_NO: // no read, no write

+      //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;

+      break;

+

+    case TT_DESCRIPTOR_PAGE_AP_RW_NO:

+    case TT_DESCRIPTOR_PAGE_AP_RW_RW:

+      // normal read/write access, do not add additional attributes

+      break;

+

+    // read only cases map to write-protect

+    case TT_DESCRIPTOR_PAGE_AP_RO_NO:

+    case TT_DESCRIPTOR_PAGE_AP_RO_RO:

+      *GcdAttributes |= EFI_MEMORY_WP;

+      break;

+

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  // now process eXectue Never attribute

+  if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {

+    *GcdAttributes |= EFI_MEMORY_XP;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+SyncCacheConfigPage (

+  IN     UINT32                             SectionIndex,

+  IN     UINT32                             FirstLevelDescriptor,

+  IN     UINTN                              NumberOfDescriptors,

+  IN     EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap,

+  IN OUT EFI_PHYSICAL_ADDRESS               *NextRegionBase,

+  IN OUT UINT64                             *NextRegionLength,

+  IN OUT UINT32                             *NextSectionAttributes

+  )

+{

+  EFI_STATUS                          Status;

+  UINT32                              i;

+  volatile ARM_PAGE_TABLE_ENTRY       *SecondLevelTable;

+  UINT32                              NextPageAttributes = 0;

+  UINT32                              PageAttributes = 0;

+  UINT32                              BaseAddress;

+  UINT64                              GcdAttributes;

+

+  // Get the Base Address from FirstLevelDescriptor;

+  BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);

+

+  // Convert SectionAttributes into PageAttributes

+  NextPageAttributes =

+      TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |

+      TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);

+

+  // obtain page table base

+  SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);

+

+  for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {

+    if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {

+      // extract attributes (cacheability and permissions)

+      PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);

+

+      if (NextPageAttributes == 0) {

+        // start on a new region

+        *NextRegionLength = 0;

+        *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);

+        NextPageAttributes = PageAttributes;

+      } else if (PageAttributes != NextPageAttributes) {

+        // Convert Section Attributes into GCD Attributes

+        Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);

+        ASSERT_EFI_ERROR (Status);

+

+        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)

+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);

+

+        // start on a new region

+        *NextRegionLength = 0;

+        *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);

+        NextPageAttributes = PageAttributes;

+      }

+    } else if (NextPageAttributes != 0) {

+      // Convert Page Attributes into GCD Attributes

+      Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);

+      ASSERT_EFI_ERROR (Status);

+

+      // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)

+      SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);

+

+      *NextRegionLength = 0;

+      *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);

+      NextPageAttributes = 0;

+    }

+    *NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE;

+  }

+

+  // Convert back PageAttributes into SectionAttributes

+  *NextSectionAttributes =

+      TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(NextPageAttributes,0) |

+      TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(NextPageAttributes);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+SyncCacheConfig (

+  IN  EFI_CPU_ARCH_PROTOCOL *CpuProtocol

+  )

+{

+  EFI_STATUS                          Status;

+  UINT32                              i;

+  EFI_PHYSICAL_ADDRESS                NextRegionBase;

+  UINT64                              NextRegionLength;

+  UINT32                              NextSectionAttributes = 0;

+  UINT32                              SectionAttributes = 0;

+  UINT64                              GcdAttributes;

+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;

+  UINTN                               NumberOfDescriptors;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap;

+

+

+  DEBUG ((EFI_D_PAGE, "SyncCacheConfig()\n"));

+

+  // This code assumes MMU is enabled and filed with section translations

+  ASSERT (ArmMmuEnabled ());

+

+  //

+  // Get the memory space map from GCD

+  //

+  MemorySpaceMap = NULL;

+  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);

+  ASSERT_EFI_ERROR (Status);

+

+

+  // The GCD implementation maintains its own copy of the state of memory space attributes.  GCD needs

+  // to know what the initial memory space attributes are.  The CPU Arch. Protocol does not provide a

+  // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were

+  // a client) to update its copy of the attributes.  This is bad architecture and should be replaced

+  // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.

+

+  // obtain page table base

+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());

+

+  // Get the first region

+  NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);

+

+  // iterate through each 1MB descriptor

+  NextRegionBase = NextRegionLength = 0;

+  for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {

+    if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {

+      // extract attributes (cacheability and permissions)

+      SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);

+

+      if (NextSectionAttributes == 0) {

+        // start on a new region

+        NextRegionLength = 0;

+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);

+        NextSectionAttributes = SectionAttributes;

+      } else if (SectionAttributes != NextSectionAttributes) {

+        // Convert Section Attributes into GCD Attributes

+        Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);

+        ASSERT_EFI_ERROR (Status);

+

+        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)

+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);

+

+        // start on a new region

+        NextRegionLength = 0;

+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);

+        NextSectionAttributes = SectionAttributes;

+      }

+      NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;

+    } else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {

+      Status = SyncCacheConfigPage (

+          i,FirstLevelTable[i],

+          NumberOfDescriptors, MemorySpaceMap,

+          &NextRegionBase,&NextRegionLength,&NextSectionAttributes);

+      ASSERT_EFI_ERROR (Status);

+    } else {

+      // We do not support yet 16MB sections

+      ASSERT ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) != TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION);

+

+      // start on a new region

+      if (NextSectionAttributes != 0) {

+        // Convert Section Attributes into GCD Attributes

+        Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);

+        ASSERT_EFI_ERROR (Status);

+

+        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)

+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);

+

+        NextRegionLength = 0;

+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);

+        NextSectionAttributes = 0;

+      }

+      NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;

+    }

+  } // section entry loop

+

+  if (NextSectionAttributes != 0) {

+    // Convert Section Attributes into GCD Attributes

+    Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);

+    ASSERT_EFI_ERROR (Status);

+

+    // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)

+    SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);

+  }

+

+  FreePool (MemorySpaceMap);

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+UpdatePageEntries (

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    Attributes,

+  IN EFI_PHYSICAL_ADDRESS      VirtualMask

+  )

+{

+  EFI_STATUS    Status;

+  UINT32        EntryValue;

+  UINT32        EntryMask;

+  UINT32        FirstLevelIdx;

+  UINT32        Offset;

+  UINT32        NumPageEntries;

+  UINT32        Descriptor;

+  UINT32        p;

+  UINT32        PageTableIndex;

+  UINT32        PageTableEntry;

+  UINT32        CurrentPageTableEntry;

+  VOID          *Mva;

+

+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;

+  volatile ARM_PAGE_TABLE_ENTRY         *PageTable;

+

+  Status = EFI_SUCCESS;

+

+  // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)

+  // EntryValue: values at bit positions specified by EntryMask

+  EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK;

+  EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;

+  // Although the PI spec is unclear on this the GCD guarantees that only

+  // one Attribute bit is set at a time, so we can safely use a switch statement

+  switch (Attributes) {

+    case EFI_MEMORY_UC:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;

+      // map to strongly ordered

+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0

+      break;

+

+    case EFI_MEMORY_WC:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;

+      // map to normal non-cachable

+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0

+      break;

+

+    case EFI_MEMORY_WT:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;

+      // write through with no-allocate

+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0

+      break;

+

+    case EFI_MEMORY_WB:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;

+      // write back (with allocate)

+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1

+      break;

+

+    case EFI_MEMORY_WP:

+    case EFI_MEMORY_XP:

+    case EFI_MEMORY_UCE:

+      // cannot be implemented UEFI definition unclear for ARM

+      // Cause a page fault if these ranges are accessed.

+      EntryValue = TT_DESCRIPTOR_PAGE_TYPE_FAULT;

+      DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));

+      break;

+

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  // Obtain page table base

+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();

+

+  // Calculate number of 4KB page table entries to change

+  NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;

+

+  // Iterate for the number of 4KB pages to change

+  Offset = 0;

+  for(p = 0; p < NumPageEntries; p++) {

+    // Calculate index into first level translation table for page table value

+

+    FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;

+    ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);

+

+    // Read the descriptor from the first level page table

+    Descriptor = FirstLevelTable[FirstLevelIdx];

+

+    // Does this descriptor need to be converted from section entry to 4K pages?

+    if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {

+      Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);

+      if (EFI_ERROR(Status)) {

+        // Exit for loop

+        break;

+      }

+

+      // Re-read descriptor

+      Descriptor = FirstLevelTable[FirstLevelIdx];

+    }

+

+    // Obtain page table base address

+    PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);

+

+    // Calculate index into the page table

+    PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;

+    ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);

+

+    // Get the entry

+    CurrentPageTableEntry = PageTable[PageTableIndex];

+

+    // Mask off appropriate fields

+    PageTableEntry = CurrentPageTableEntry & ~EntryMask;

+

+    // Mask in new attributes and/or permissions

+    PageTableEntry |= EntryValue;

+

+    if (VirtualMask != 0) {

+      // Make this virtual address point at a physical page

+      PageTableEntry &= ~VirtualMask;

+    }

+

+    if (CurrentPageTableEntry  != PageTableEntry) {

+      Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));

+      if ((CurrentPageTableEntry & TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) == TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) {

+        // The current section mapping is cacheable so Clean/Invalidate the MVA of the page

+        // Note assumes switch(Attributes), not ARMv7 possibilities

+        WriteBackInvalidateDataCacheRange (Mva, TT_DESCRIPTOR_PAGE_SIZE);

+      }

+

+      // Only need to update if we are changing the entry

+      PageTable[PageTableIndex] = PageTableEntry;

+      ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);

+    }

+

+    Status = EFI_SUCCESS;

+    Offset += TT_DESCRIPTOR_PAGE_SIZE;

+

+  } // End first level translation table loop

+

+  return Status;

+}

+

+

+

+EFI_STATUS

+UpdateSectionEntries (

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    Attributes,

+  IN EFI_PHYSICAL_ADDRESS      VirtualMask

+  )

+{

+  EFI_STATUS    Status = EFI_SUCCESS;

+  UINT32        EntryMask;

+  UINT32        EntryValue;

+  UINT32        FirstLevelIdx;

+  UINT32        NumSections;

+  UINT32        i;

+  UINT32        CurrentDescriptor;

+  UINT32        Descriptor;

+  VOID          *Mva;

+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;

+

+  // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)

+  // EntryValue: values at bit positions specified by EntryMask

+

+  // Make sure we handle a section range that is unmapped

+  EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK;

+  EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;

+

+  // Although the PI spec is unclear on this the GCD guarantees that only

+  // one Attribute bit is set at a time, so we can safely use a switch statement

+  switch(Attributes) {

+    case EFI_MEMORY_UC:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;

+      // map to strongly ordered

+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0

+      break;

+

+    case EFI_MEMORY_WC:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;

+      // map to normal non-cachable

+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0

+      break;

+

+    case EFI_MEMORY_WT:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;

+      // write through with no-allocate

+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0

+      break;

+

+    case EFI_MEMORY_WB:

+      // modify cacheability attributes

+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;

+      // write back (with allocate)

+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1

+      break;

+

+    case EFI_MEMORY_WP:

+    case EFI_MEMORY_XP:

+    case EFI_MEMORY_RP:

+    case EFI_MEMORY_UCE:

+      // cannot be implemented UEFI definition unclear for ARM

+      // Cause a page fault if these ranges are accessed.

+      EntryValue = TT_DESCRIPTOR_SECTION_TYPE_FAULT;

+      DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));

+      break;

+

+

+    default:

+      return EFI_UNSUPPORTED;

+  }

+

+  // obtain page table base

+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();

+

+  // calculate index into first level translation table for start of modification

+  FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;

+  ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);

+

+  // calculate number of 1MB first level entries this applies to

+  NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;

+

+  // iterate through each descriptor

+  for(i=0; i<NumSections; i++) {

+    CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];

+

+    // has this descriptor already been coverted to pages?

+    if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {

+      // forward this 1MB range to page table function instead

+      Status = UpdatePageEntries ((FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, TT_DESCRIPTOR_SECTION_SIZE, Attributes, VirtualMask);

+    } else {

+      // still a section entry

+

+      // mask off appropriate fields

+      Descriptor = CurrentDescriptor & ~EntryMask;

+

+      // mask in new attributes and/or permissions

+      Descriptor |= EntryValue;

+      if (VirtualMask != 0) {

+        Descriptor &= ~VirtualMask;

+      }

+

+      if (CurrentDescriptor  != Descriptor) {

+        Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);

+        if ((CurrentDescriptor & TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) == TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) {

+          // The current section mapping is cacheable so Clean/Invalidate the MVA of the section

+          // Note assumes switch(Attributes), not ARMv7 possabilities

+          WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB);

+        }

+

+        // Only need to update if we are changing the descriptor

+        FirstLevelTable[FirstLevelIdx + i] = Descriptor;

+        ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);

+      }

+

+      Status = EFI_SUCCESS;

+    }

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+ConvertSectionToPages (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress

+  )

+{

+  EFI_STATUS              Status;

+  EFI_PHYSICAL_ADDRESS    PageTableAddr;

+  UINT32                  FirstLevelIdx;

+  UINT32                  SectionDescriptor;

+  UINT32                  PageTableDescriptor;

+  UINT32                  PageDescriptor;

+  UINT32                  Index;

+

+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;

+  volatile ARM_PAGE_TABLE_ENTRY         *PageTable;

+

+  DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));

+

+  // Obtain page table base

+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();

+

+  // Calculate index into first level translation table for start of modification

+  FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;

+  ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);

+

+  // Get section attributes and convert to page attributes

+  SectionDescriptor = FirstLevelTable[FirstLevelIdx];

+  PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);

+

+  // Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)

+  Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, 1, &PageTableAddr);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;

+

+  // Write the page table entries out

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

+    PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor;

+  }

+

+  // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks

+  WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, TT_DESCRIPTOR_PAGE_SIZE);

+

+  // Formulate page table entry, Domain=0, NS=0

+  PageTableDescriptor = (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;

+

+  // Write the page table entry out, replacing section entry

+  FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;

+

+  return EFI_SUCCESS;

+}

+

+

+

+EFI_STATUS

+SetMemoryAttributes (

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    Attributes,

+  IN EFI_PHYSICAL_ADDRESS      VirtualMask

+  )

+{

+  EFI_STATUS    Status;

+

+  if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) {

+    // Is the base and length a multiple of 1 MB?

+    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));

+    Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask);

+  } else {

+    // Base and/or length is not a multiple of 1 MB

+    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));

+    Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask);

+  }

+

+  // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks

+  // flush and invalidate pages

+  //TODO: Do we really need to invalidate the caches everytime we change the memory attributes ?

+  ArmCleanInvalidateDataCache ();

+

+  ArmInvalidateInstructionCache ();

+

+  // Invalidate all TLB entries so changes are synced

+  ArmInvalidateTlb ();

+

+  return Status;

+}

+

+UINT64

+EfiAttributeToArmAttribute (

+  IN UINT64                    EfiAttributes

+  )

+{

+  UINT64 ArmAttributes;

+

+  switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {

+    case EFI_MEMORY_UC:

+      // Map to strongly ordered

+      ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0

+      break;

+

+    case EFI_MEMORY_WC:

+      // Map to normal non-cachable

+      ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0

+      break;

+

+    case EFI_MEMORY_WT:

+      // Write through with no-allocate

+      ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0

+      break;

+

+    case EFI_MEMORY_WB:

+      // Write back (with allocate)

+      ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1

+      break;

+

+    case EFI_MEMORY_WP:

+    case EFI_MEMORY_XP:

+    case EFI_MEMORY_RP:

+    case EFI_MEMORY_UCE:

+    default:

+      // Cannot be implemented UEFI definition unclear for ARM

+      // Cause a page fault if these ranges are accessed.

+      ArmAttributes = TT_DESCRIPTOR_SECTION_TYPE_FAULT;

+      DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): Unsupported attribute %x will page fault on access\n", EfiAttributes));

+      break;

+  }

+

+  // Determine protection attributes

+  if (EfiAttributes & EFI_MEMORY_WP) {

+    ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO;

+  } else {

+    ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW;

+  }

+

+  // Determine eXecute Never attribute

+  if (EfiAttributes & EFI_MEMORY_XP) {

+    ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;

+  }

+

+  return ArmAttributes;

+}

+

+EFI_STATUS

+GetMemoryRegionPage (

+  IN     UINT32                  *PageTable,

+  IN OUT UINTN                   *BaseAddress,

+  OUT    UINTN                   *RegionLength,

+  OUT    UINTN                   *RegionAttributes

+  )

+{

+  UINT32      PageAttributes;

+  UINT32      TableIndex;

+  UINT32      PageDescriptor;

+

+  // Convert the section attributes into page attributes

+  PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes, 0);

+

+  // Calculate index into first level translation table for start of modification

+  TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK)  >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;

+  ASSERT (TableIndex < TRANSLATION_TABLE_PAGE_COUNT);

+

+  // Go through the page table to find the end of the section

+  for (; TableIndex < TRANSLATION_TABLE_PAGE_COUNT; TableIndex++) {

+    // Get the section at the given index

+    PageDescriptor = PageTable[TableIndex];

+

+    if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) {

+      // Case: End of the boundary of the region

+      return EFI_SUCCESS;

+    } else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {

+      if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {

+        *RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;

+      } else {

+        // Case: End of the boundary of the region

+        return EFI_SUCCESS;

+      }

+    } else {

+      // We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.

+      ASSERT(0);

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+GetMemoryRegion (

+  IN OUT UINTN                   *BaseAddress,

+  OUT    UINTN                   *RegionLength,

+  OUT    UINTN                   *RegionAttributes

+  )

+{

+  EFI_STATUS                  Status;

+  UINT32                      TableIndex;

+  UINT32                      PageAttributes;

+  UINT32                      PageTableIndex;

+  UINT32                      SectionDescriptor;

+  ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;

+  UINT32                     *PageTable;

+

+  // Initialize the arguments

+  *RegionLength = 0;

+

+  // Obtain page table base

+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();

+

+  // Calculate index into first level translation table for start of modification

+  TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;

+  ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);

+

+  // Get the section at the given index

+  SectionDescriptor = FirstLevelTable[TableIndex];

+

+  // If 'BaseAddress' belongs to the section then round it to the section boundary

+  if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||

+      ((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION))

+  {

+    *BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK;

+    *RegionAttributes = SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK;

+  } else {

+    // Otherwise, we round it to the page boundary

+    *BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK;

+

+    // Get the attribute at the page table level (Level 2)

+    PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);

+

+    // Calculate index into first level translation table for start of modification

+    PageTableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK)  >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;

+    ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);

+

+    PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK;

+    *RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes, 0) |

+                        TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes);

+  }

+

+  for (;TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {

+    // Get the section at the given index

+    SectionDescriptor = FirstLevelTable[TableIndex];

+

+    // If the entry is a level-2 page table then we scan it to find the end of the region

+    if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) {

+      // Extract the page table location from the descriptor

+      PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);

+

+      // Scan the page table to find the end of the region.

+      Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);

+

+      // If we have found the end of the region (Status == EFI_SUCCESS) then we exit the for-loop

+      if (Status == EFI_SUCCESS) {

+        break;

+      }

+    } else if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||

+               ((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION)) {

+      if ((SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK) != *RegionAttributes) {

+        // If the attributes of the section differ from the one targeted then we exit the loop

+        break;

+      } else {

+        *RegionLength = *RegionLength + TT_DESCRIPTOR_SECTION_SIZE;

+      }

+    } else {

+      // If we are on an invalid section then it means it is the end of our section.

+      break;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.c
new file mode 100644
index 0000000..0c49acb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.c
@@ -0,0 +1,280 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#include "CpuDxe.h"

+

+#include <Guid/IdleLoopEvent.h>

+

+BOOLEAN mInterruptState   = FALSE;

+

+

+/**

+  This function flushes the range of addresses from Start to Start+Length

+  from the processor's data cache. If Start is not aligned to a cache line

+  boundary, then the bytes before Start to the preceding cache line boundary

+  are also flushed. If Start+Length is not aligned to a cache line boundary,

+  then the bytes past Start+Length to the end of the next cache line boundary

+  are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be

+  supported. If the data cache is fully coherent with all DMA operations, then

+  this function can just return EFI_SUCCESS. If the processor does not support

+  flushing a range of the data cache, then the entire data cache can be flushed.

+

+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  Start            The beginning physical address to flush from the processor's data

+                           cache.

+  @param  Length           The number of bytes to flush from the processor's data cache. This

+                           function may flush more bytes than Length specifies depending upon

+                           the granularity of the flush operation that the processor supports.

+  @param  FlushType        Specifies the type of flush operation to perform.

+

+  @retval EFI_SUCCESS           The address range from Start to Start+Length was flushed from

+                                the processor's data cache.

+  @retval EFI_UNSUPPORTEDT      The processor does not support the cache flush type specified

+                                by FlushType.

+  @retval EFI_DEVICE_ERROR      The address range from Start to Start+Length could not be flushed

+                                from the processor's data cache.

+

+**/

+EFI_STATUS

+EFIAPI

+CpuFlushCpuDataCache (

+  IN EFI_CPU_ARCH_PROTOCOL           *This,

+  IN EFI_PHYSICAL_ADDRESS            Start,

+  IN UINT64                          Length,

+  IN EFI_CPU_FLUSH_TYPE              FlushType

+  )

+{

+

+  switch (FlushType) {

+    case EfiCpuFlushTypeWriteBack:

+      WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);

+      break;

+    case EfiCpuFlushTypeInvalidate:

+      InvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);

+      break;

+    case EfiCpuFlushTypeWriteBackInvalidate:

+      WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);

+      break;

+    default:

+      return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  This function enables interrupt processing by the processor.

+

+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           Interrupts are enabled on the processor.

+  @retval EFI_DEVICE_ERROR      Interrupts could not be enabled on the processor.

+

+**/

+EFI_STATUS

+EFIAPI

+CpuEnableInterrupt (

+  IN EFI_CPU_ARCH_PROTOCOL          *This

+  )

+{

+  ArmEnableInterrupts ();

+

+  mInterruptState  = TRUE;

+  return EFI_SUCCESS;

+}

+

+

+/**

+  This function disables interrupt processing by the processor.

+

+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           Interrupts are disabled on the processor.

+  @retval EFI_DEVICE_ERROR      Interrupts could not be disabled on the processor.

+

+**/

+EFI_STATUS

+EFIAPI

+CpuDisableInterrupt (

+  IN EFI_CPU_ARCH_PROTOCOL          *This

+  )

+{

+  ArmDisableInterrupts ();

+

+  mInterruptState = FALSE;

+  return EFI_SUCCESS;

+}

+

+

+/**

+  This function retrieves the processor's current interrupt state a returns it in

+  State. If interrupts are currently enabled, then TRUE is returned. If interrupts

+  are currently disabled, then FALSE is returned.

+

+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  State            A pointer to the processor's current interrupt state. Set to TRUE if

+                           interrupts are enabled and FALSE if interrupts are disabled.

+

+  @retval EFI_SUCCESS           The processor's current interrupt state was returned in State.

+  @retval EFI_INVALID_PARAMETER State is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+CpuGetInterruptState (

+  IN  EFI_CPU_ARCH_PROTOCOL         *This,

+  OUT BOOLEAN                       *State

+  )

+{

+  if (State == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *State = mInterruptState;

+  return EFI_SUCCESS;

+}

+

+

+/**

+  This function generates an INIT on the processor. If this function succeeds, then the

+  processor will be reset, and control will not be returned to the caller. If InitType is

+  not supported by this processor, or the processor cannot programmatically generate an

+  INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error

+  occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.

+

+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.

+  @param  InitType         The type of processor INIT to perform.

+

+  @retval EFI_SUCCESS           The processor INIT was performed. This return code should never be seen.

+  @retval EFI_UNSUPPORTED       The processor INIT operation specified by InitType is not supported

+                                by this processor.

+  @retval EFI_DEVICE_ERROR      The processor INIT failed.

+

+**/

+EFI_STATUS

+EFIAPI

+CpuInit (

+  IN EFI_CPU_ARCH_PROTOCOL           *This,

+  IN EFI_CPU_INIT_TYPE               InitType

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+EFIAPI

+CpuRegisterInterruptHandler (

+  IN EFI_CPU_ARCH_PROTOCOL          *This,

+  IN EFI_EXCEPTION_TYPE             InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler

+  )

+{

+  return RegisterInterruptHandler (InterruptType, InterruptHandler);

+}

+

+EFI_STATUS

+EFIAPI

+CpuGetTimerValue (

+  IN  EFI_CPU_ARCH_PROTOCOL          *This,

+  IN  UINT32                         TimerIndex,

+  OUT UINT64                         *TimerValue,

+  OUT UINT64                         *TimerPeriod   OPTIONAL

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  Callback function for idle events.

+

+  @param  Event                 Event whose notification function is being invoked.

+  @param  Context               The pointer to the notification function's context,

+                                which is implementation-dependent.

+

+**/

+VOID

+EFIAPI

+IdleLoopEventCallback (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  )

+{

+  CpuSleep ();

+}

+

+//

+// Globals used to initialize the protocol

+//

+EFI_HANDLE            mCpuHandle = NULL;

+EFI_CPU_ARCH_PROTOCOL mCpu = {

+  CpuFlushCpuDataCache,

+  CpuEnableInterrupt,

+  CpuDisableInterrupt,

+  CpuGetInterruptState,

+  CpuInit,

+  CpuRegisterInterruptHandler,

+  CpuGetTimerValue,

+  CpuSetMemoryAttributes,

+  0,          // NumberOfTimers

+  4,          // DmaBufferAlignment

+};

+

+EFI_STATUS

+CpuDxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  EFI_EVENT    IdleLoopEvent;

+

+  InitializeExceptions (&mCpu);

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                &mCpuHandle,

+                &gEfiCpuArchProtocolGuid,           &mCpu,

+                &gVirtualUncachedPagesProtocolGuid, &gVirtualUncachedPages,

+                NULL

+                );

+

+  //

+  // Make sure GCD and MMU settings match. This API calls gDS->SetMemorySpaceAttributes ()

+  // and that calls EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes, so this code needs to go

+  // after the protocol is installed

+  //

+  SyncCacheConfig (&mCpu);

+

+  // If the platform is a MPCore system then install the Configuration Table describing the

+  // secondary core states

+  if (ArmIsMpCore()) {

+    PublishArmProcessorTable();

+  }

+

+  //

+  // Setup a callback for idle events

+  //

+  Status = gBS->CreateEventEx (

+                  EVT_NOTIFY_SIGNAL,

+                  TPL_NOTIFY,

+                  IdleLoopEventCallback,

+                  NULL,

+                  &gIdleLoopEventGuid,

+                  &IdleLoopEvent

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.h
new file mode 100644
index 0000000..d16abe4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -0,0 +1,182 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __CPU_DXE_ARM_EXCEPTION_H__

+#define __CPU_DXE_ARM_EXCEPTION_H__

+

+#include <Uefi.h>

+

+#include <Library/ArmLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/CacheMaintenanceLib.h>

+#include <Library/PeCoffGetEntryPointLib.h>

+#include <Library/UefiLib.h>

+#include <Library/CpuLib.h>

+#include <Library/DefaultExceptionHandlerLib.h>

+#include <Library/DebugLib.h>

+

+#include <Guid/DebugImageInfoTable.h>

+#include <Protocol/Cpu.h>

+#include <Protocol/DebugSupport.h>

+#include <Protocol/DebugSupportPeriodicCallback.h>

+#include <Protocol/VirtualUncachedPages.h>

+#include <Protocol/LoadedImage.h>

+

+

+#define EFI_MEMORY_CACHETYPE_MASK     (EFI_MEMORY_UC  | \

+                                       EFI_MEMORY_WC  | \

+                                       EFI_MEMORY_WT  | \

+                                       EFI_MEMORY_WB  | \

+                                       EFI_MEMORY_UCE   \

+                                       )

+

+

+/**

+  This function registers and enables the handler specified by InterruptHandler for a processor

+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the

+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.

+  The installed handler is called once for each processor interrupt or exception.

+

+  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts

+                           are enabled and FALSE if interrupts are disabled.

+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called

+                           when a processor interrupt occurs. If this parameter is NULL, then the handler

+                           will be uninstalled.

+

+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.

+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was

+                                previously installed.

+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not

+                                previously installed.

+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.

+

+**/

+EFI_STATUS

+RegisterInterruptHandler (

+  IN EFI_EXCEPTION_TYPE             InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler

+  );

+

+

+/**

+  This function registers and enables the handler specified by InterruptHandler for a processor

+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the

+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.

+  The installed handler is called once for each processor interrupt or exception.

+

+  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts

+                           are enabled and FALSE if interrupts are disabled.

+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called

+                           when a processor interrupt occurs. If this parameter is NULL, then the handler

+                           will be uninstalled.

+

+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.

+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was

+                                previously installed.

+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not

+                                previously installed.

+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.

+

+**/

+EFI_STATUS

+RegisterDebuggerInterruptHandler (

+  IN EFI_EXCEPTION_TYPE             InterruptType,

+  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler

+  );

+

+

+EFI_STATUS

+EFIAPI

+CpuSetMemoryAttributes (

+  IN EFI_CPU_ARCH_PROTOCOL     *This,

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    Attributes

+  );

+

+EFI_STATUS

+InitializeExceptions (

+  IN EFI_CPU_ARCH_PROTOCOL    *Cpu

+  );

+

+EFI_STATUS

+SyncCacheConfig (

+  IN  EFI_CPU_ARCH_PROTOCOL *CpuProtocol

+  );

+

+EFI_STATUS

+ConvertSectionToPages (

+  IN EFI_PHYSICAL_ADDRESS  BaseAddress

+  );

+

+/**

+ * Publish ARM Processor Data table in UEFI SYSTEM Table.

+ * @param  HobStart               Pointer to the beginning of the HOB List from PEI.

+ *

+ * Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.

+ *               If  the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory

+ *               and a pointer is assigned to it in ARM processor table. Then the ARM processor table is

+ *               installed in EFI configuration table.

+**/

+VOID

+EFIAPI

+PublishArmProcessorTable(

+  VOID

+  );

+

+EFI_STATUS

+SetMemoryAttributes (

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    Attributes,

+  IN EFI_PHYSICAL_ADDRESS      VirtualMask

+  );

+

+// The ARM Attributes might be defined on 64-bit (case of the long format description table)

+UINT64

+EfiAttributeToArmAttribute (

+  IN UINT64                    EfiAttributes

+  );

+

+EFI_STATUS

+GetMemoryRegion (

+  IN OUT UINTN                   *BaseAddress,

+  OUT    UINTN                   *RegionLength,

+  OUT    UINTN                   *RegionAttributes

+  );

+

+VOID

+GetRootTranslationTableInfo (

+  IN  UINTN    T0SZ,

+  OUT UINTN   *TableLevel,

+  OUT UINTN   *TableEntryCount

+  );

+

+EFI_STATUS

+SetGcdMemorySpaceAttributes (

+  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap,

+  IN UINTN                               NumberOfDescriptors,

+  IN EFI_PHYSICAL_ADDRESS                BaseAddress,

+  IN UINT64                              Length,

+  IN UINT64                              Attributes

+  );

+

+extern VIRTUAL_UNCACHED_PAGES_PROTOCOL  gVirtualUncachedPages;

+

+#endif // __CPU_DXE_ARM_EXCEPTION_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
new file mode 100644
index 0000000..01f65a3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
@@ -0,0 +1,93 @@
+#/** @file

+#

+#  DXE CPU driver

+#

+#  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>

+#  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.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmCpuDxe

+  FILE_GUID                      = B8D9777E-D72A-451F-9BDB-BAFB52A68415

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = CpuDxeInitialize

+

+[Sources.Common]

+  CpuDxe.c

+  CpuDxe.h

+  CpuMpCore.c

+  CpuMmuCommon.c

+

+#

+# Prior to ARMv6 we have multiple stacks, one per mode

+#

+#  ArmV4/ExceptionSupport.asm | RVCT

+#  ArmV4/ExceptionSupport.S   | GCC

+

+#

+# ARMv6 or later uses a single stack via srs/stm instructions

+#

+

+[Sources.ARM]

+  ArmV6/Mmu.c

+  ArmV6/Exception.c

+  ArmV6/ExceptionSupport.asm | RVCT

+  ArmV6/ExceptionSupport.S   | GCC

+

+[Sources.AARCH64]

+  AArch64/Mmu.c

+  AArch64/Exception.c

+  AArch64/ExceptionSupport.S

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+

+[LibraryClasses]

+  ArmLib

+  BaseMemoryLib

+  CacheMaintenanceLib

+  CpuLib

+  DebugLib

+  DefaultExceptionHandlerLib

+  DxeServicesTableLib

+  HobLib

+  PeCoffGetEntryPointLib

+  UefiDriverEntryPoint

+  UefiLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+  gEfiDebugSupportPeriodicCallbackProtocolGuid

+  gVirtualUncachedPagesProtocolGuid

+

+[Guids]

+  gEfiDebugImageInfoTableGuid

+  gArmMpCoreInfoGuid

+  gIdleLoopEventGuid

+

+[Pcd.common]

+  gArmTokenSpaceGuid.PcdVFPEnabled

+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress

+

+[FeaturePcd.common]

+  gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport

+  gArmTokenSpaceGuid.PcdRelocateVectorTable

+  gArmTokenSpaceGuid.PcdDebuggerExceptionSupport

+

+[Depex]

+  TRUE

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

+};

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMpCore.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMpCore.c
new file mode 100644
index 0000000..81d858e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMpCore.c
@@ -0,0 +1,103 @@
+/** @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.

+*

+**/

+

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/HobLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+

+#include <Guid/ArmMpCoreInfo.h>

+

+ARM_PROCESSOR_TABLE mArmProcessorTableTemplate = {

+  {

+    EFI_ARM_PROCESSOR_TABLE_SIGNATURE,

+    0,

+    EFI_ARM_PROCESSOR_TABLE_REVISION,

+    EFI_ARM_PROCESSOR_TABLE_OEM_ID,

+    EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID,

+    EFI_ARM_PROCESSOR_TABLE_OEM_REVISION,

+    EFI_ARM_PROCESSOR_TABLE_CREATOR_ID,

+    EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION,

+    { 0 },

+    0

+  },   //ARM Processor table header

+  0,   // Number of entries in ARM processor Table

+  NULL // ARM Processor Table

+};

+

+/** Publish ARM Processor Data table in UEFI SYSTEM Table.

+ * @param:  HobStart               Pointer to the beginning of the HOB List from PEI.

+ *

+ * Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.

+ *               If  the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory

+ *               and a pointer is assigned to it in ARM processor table. Then the ARM processor table is

+ *               installed in EFI configuration table.

+**/

+VOID

+EFIAPI

+PublishArmProcessorTable (

+  VOID

+  )

+{

+  EFI_PEI_HOB_POINTERS    Hob;

+

+  Hob.Raw = GetHobList ();

+

+  // Iterate through the HOBs and find if there is ARM PROCESSOR ENTRY HOB

+  for (; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {

+    // Check for Correct HOB type

+    if ((GET_HOB_TYPE (Hob)) == EFI_HOB_TYPE_GUID_EXTENSION) {

+      // Check for correct GUID type

+      if (CompareGuid(&(Hob.Guid->Name), &gArmMpCoreInfoGuid)) {

+        ARM_PROCESSOR_TABLE     *ArmProcessorTable;

+        EFI_STATUS              Status;

+

+        // Allocate Runtime memory for ARM processor table

+        ArmProcessorTable = (ARM_PROCESSOR_TABLE*)AllocateRuntimePool(sizeof(ARM_PROCESSOR_TABLE));

+

+        // Check if the memory allocation is succesful or not

+        ASSERT(NULL != ArmProcessorTable);

+

+        // Set ARM processor table to default values

+        CopyMem(ArmProcessorTable,&mArmProcessorTableTemplate,sizeof(ARM_PROCESSOR_TABLE));

+

+        // Fill in Length fields of ARM processor table

+        ArmProcessorTable->Header.Length = sizeof(ARM_PROCESSOR_TABLE);

+        ArmProcessorTable->Header.DataLen = GET_GUID_HOB_DATA_SIZE(Hob);

+

+        // Fill in Identifier(ARM processor table GUID)

+        ArmProcessorTable->Header.Identifier = gArmMpCoreInfoGuid;

+

+        // Set Number of ARM core entries in the Table

+        ArmProcessorTable->NumberOfEntries = GET_GUID_HOB_DATA_SIZE(Hob)/sizeof(ARM_CORE_INFO);

+

+        // Allocate runtime memory for ARM processor Table entries

+        ArmProcessorTable->ArmCpus = (ARM_CORE_INFO*)AllocateRuntimePool (

+           ArmProcessorTable->NumberOfEntries * sizeof(ARM_CORE_INFO));

+

+        // Check if the memory allocation is succesful or not

+        ASSERT(NULL != ArmProcessorTable->ArmCpus);

+

+        // Copy ARM Processor Table data from HOB list to newly allocated memory

+        CopyMem(ArmProcessorTable->ArmCpus,GET_GUID_HOB_DATA(Hob), ArmProcessorTable->Header.DataLen);

+

+        // Install the ARM Processor table into EFI system configuration table

+        Status = gBS->InstallConfigurationTable (&gArmMpCoreInfoGuid, ArmProcessorTable);

+

+        ASSERT_EFI_ERROR (Status);

+      }

+    }

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.c
new file mode 100755
index 0000000..d54f42a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.c
@@ -0,0 +1,91 @@
+/**@file

+

+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>

+Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR>

+Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>

+

+This program and the accompanying materials

+are licensed and made available under the terms and conditions of the BSD License

+which accompanies this distribution.  The full text of the license may be found at

+http://opensource.org/licenses/bsd-license.php

+

+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+Module Name:

+

+  MemoryInit.c

+

+Abstract:

+

+  PEIM to provide fake memory init

+

+**/

+

+

+

+//

+// The package level header files this module uses

+//

+#include <PiPei.h>

+//

+// The protocols, PPI and GUID defintions for this module

+//

+#include <Ppi/ArmMpCoreInfo.h>

+

+//

+// The Library classes this module consumes

+//

+#include <Library/DebugLib.h>

+#include <Library/PeimEntryPoint.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/PcdLib.h>

+#include <Library/HobLib.h>

+#include <Library/ArmLib.h>

+

+/*++

+

+Routine Description:

+

+Arguments:

+

+  FileHandle  - Handle of the file being invoked.

+  PeiServices - Describes the list of possible PEI Services.

+

+Returns:

+

+  Status -  EFI_SUCCESS if the boot mode could be set

+

+--*/

+EFI_STATUS

+EFIAPI

+InitializeCpuPeim (

+  IN       EFI_PEI_FILE_HANDLE  FileHandle,

+  IN CONST EFI_PEI_SERVICES     **PeiServices

+  )

+{

+  EFI_STATUS              Status;

+  ARM_MP_CORE_INFO_PPI    *ArmMpCoreInfoPpi;

+  UINTN                   ArmCoreCount;

+  ARM_CORE_INFO           *ArmCoreInfoTable;

+

+  // Enable program flow prediction, if supported.

+  ArmEnableBranchPrediction ();

+

+  // Publish the CPU memory and io spaces sizes

+  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));

+

+  // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid

+  Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi);

+  if (!EFI_ERROR(Status)) {

+    // Build the MP Core Info Table

+    ArmCoreCount = 0;

+    Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);

+    if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {

+      // Build MPCore Info HOB

+      BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.inf b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.inf
new file mode 100755
index 0000000..eafccd6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.inf
@@ -0,0 +1,58 @@
+## @file

+# Component description file for BootMode module

+#

+# This module provides platform specific function to detect boot mode.

+# Copyright (c) 2006 - 2010, Intel Corporation. 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                      = CpuPei

+  FILE_GUID                      = 2FD8B7AD-F8FA-4021-9FC0-0AA572147CDC

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InitializeCpuPeim

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = ARM

+#

+

+[Sources]

+  CpuPei.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  PeimEntryPoint

+  DebugLib

+  HobLib

+  ArmLib

+

+[Ppis]

+  gArmMpCoreInfoPpiGuid

+

+[Guids]

+  gArmMpCoreInfoGuid

+

+[FixedPcd]

+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize

+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize

+

+[Depex]

+  gEfiPeiMemoryDiscoveredPpiGuid

+

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
new file mode 100644
index 0000000..578fd1e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
@@ -0,0 +1,29 @@
+/** @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.

+*

+**/

+#ifndef __GENERIC_WATCHDOG_H__

+#define __GENERIC_WATCHDOG_H__

+

+// Refresh Frame:

+#define GENERIC_WDOG_REFRESH_REG              ((UINT32)FixedPcdGet32 (PcdGenericWatchdogRefreshBase) + 0x000)

+

+// Control Frame:

+#define GENERIC_WDOG_CONTROL_STATUS_REG       ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x000)

+#define GENERIC_WDOG_OFFSET_REG               ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x008)

+#define GENERIC_WDOG_COMPARE_VALUE_REG        ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x010)

+

+// Values of bit 0 of the Control/Status Register

+#define GENERIC_WDOG_ENABLED          1

+#define GENERIC_WDOG_DISABLED         0

+

+#endif  // __GENERIC_WATCHDOG_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
new file mode 100644
index 0000000..b1d9c02
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -0,0 +1,354 @@
+/** @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 <PiDxe.h>

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/ArmGenericTimerCounterLib.h>

+

+#include <Protocol/WatchdogTimer.h>

+#include <Protocol/HardwareInterrupt.h>

+

+#include "GenericWatchdog.h"

+

+// The number of 100ns periods (the unit of time passed to these functions)

+// in a second

+#define TIME_UNITS_PER_SECOND 10000000

+

+// Tick frequency of the generic timer that is the basis of the generic watchdog

+UINTN mTimerFrequencyHz = 0;

+

+// In cases where the compare register was set manually, information about

+// how long the watchdog was asked to wait cannot be retrieved from hardware.

+// It is therefore stored here. 0 means the timer is not running.

+UINT64 mNumTimerTicks = 0;

+

+EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;

+

+EFI_STATUS

+WatchdogWriteOffsetRegister (

+  UINT32  Value

+  )

+{

+  return MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);

+}

+

+EFI_STATUS

+WatchdogWriteCompareRegister (

+  UINT64  Value

+  )

+{

+  return MmioWrite64 (GENERIC_WDOG_COMPARE_VALUE_REG, Value);

+}

+

+EFI_STATUS

+WatchdogEnable (

+  VOID

+  )

+{

+  return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_ENABLED);

+}

+

+EFI_STATUS

+WatchdogDisable (

+  VOID

+  )

+{

+  return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);

+}

+

+/**

+    On exiting boot services we must make sure the Watchdog Timer

+    is stopped.

+**/

+VOID

+EFIAPI

+WatchdogExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  WatchdogDisable ();

+  mNumTimerTicks = 0;

+}

+

+/*

+  This function is called when the watchdog's first signal (WS0) goes high.

+  It uses the ResetSystem Runtime Service to reset the board.

+*/

+VOID

+EFIAPI

+WatchdogInterruptHandler (

+  IN  HARDWARE_INTERRUPT_SOURCE   Source,

+  IN  EFI_SYSTEM_CONTEXT          SystemContext

+  )

+{

+  STATIC CONST CHAR16      ResetString[] = L"The generic watchdog timer ran out.";

+

+  WatchdogDisable ();

+

+  mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);

+

+  gRT->ResetSystem (

+         EfiResetCold,

+         EFI_TIMEOUT,

+         StrSize (ResetString),

+         &ResetString

+         );

+

+  // If we got here then the reset didn't work

+  ASSERT (FALSE);

+}

+

+/**

+  This function registers the handler NotifyFunction so it is called every time

+  the watchdog timer expires.  It also passes the amount of time since the last

+  handler call to the NotifyFunction.

+  If NotifyFunction is not NULL and a handler is not already registered,

+  then the new handler is registered and EFI_SUCCESS is returned.

+  If NotifyFunction is NULL, and a handler is already registered,

+  then that handler is unregistered.

+  If an attempt is made to register a handler when a handler is already registered,

+  then EFI_ALREADY_STARTED is returned.

+  If an attempt is made to unregister a handler when a handler is not registered,

+  then EFI_INVALID_PARAMETER is returned.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  NotifyFunction   The function to call when a timer interrupt fires.

+                           This function executes at TPL_HIGH_LEVEL. The DXE

+                           Core will register a handler for the timer interrupt,

+                           so it can know how much time has passed. This

+                           information is used to signal timer based events.

+                           NULL will unregister the handler.

+

+  @retval EFI_SUCCESS           The watchdog timer handler was registered.

+  @retval EFI_ALREADY_STARTED   NotifyFunction is not NULL, and a handler is already

+                                registered.

+  @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not

+                                previously registered.

+

+**/

+EFI_STATUS

+EFIAPI

+WatchdogRegisterHandler (

+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,

+  IN EFI_WATCHDOG_TIMER_NOTIFY                NotifyFunction

+  )

+{

+  // ERROR: This function is not supported.

+  // The watchdog will reset the board

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  This function sets the amount of time to wait before firing the watchdog

+  timer to TimerPeriod 100 nS units.  If TimerPeriod is 0, then the watchdog

+  timer is disabled.

+

+  @param  This             The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod      The amount of time in 100 nS units to wait before the watchdog

+                           timer is fired. If TimerPeriod is zero, then the watchdog

+                           timer is disabled.

+

+  @retval EFI_SUCCESS           The watchdog timer has been programmed to fire in Time

+                                100 nS units.

+  @retval EFI_DEVICE_ERROR      A watchdog timer could not be programmed due to a device

+                                error.

+

+**/

+EFI_STATUS

+EFIAPI

+WatchdogSetTimerPeriod (

+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,

+  IN UINT64                                   TimerPeriod   // In 100ns units

+  )

+{

+  UINTN       SystemCount;

+  EFI_STATUS  Status;

+

+  // if TimerPerdiod is 0, this is a request to stop the watchdog.

+  if (TimerPeriod == 0) {

+    mNumTimerTicks = 0;

+    return WatchdogDisable ();

+  }

+

+  // Work out how many timer ticks will equate to TimerPeriod

+  mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;

+

+  //

+  // If the number of required ticks is greater than the max number the

+  // watchdog's offset register (WOR) can hold, we need to manually compute and

+  // set the compare register (WCV)

+  //

+  if (mNumTimerTicks > MAX_UINT32) {

+    //

+    // We need to enable the watchdog *before* writing to the compare register,

+    // because enabling the watchdog causes an "explicit refresh", which

+    // clobbers the compare register (WCV). In order to make sure this doesn't

+    // trigger an interrupt, set the offset to max.

+    //

+    Status = WatchdogWriteOffsetRegister (MAX_UINT32);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    WatchdogEnable ();

+    SystemCount = ArmGenericTimerGetSystemCount ();

+    Status      = WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);

+  } else {

+    Status = WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);

+    WatchdogEnable ();

+  }

+

+  return Status;

+}

+

+/**

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod      A pointer to the timer period to retrieve in 100

+                           ns units. If 0 is returned, then the timer is

+                           currently disabled.

+

+

+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.

+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+WatchdogGetTimerPeriod (

+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                                  *TimerPeriod

+  )

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Interface structure for the Watchdog Architectural Protocol.

+

+  @par Protocol Description:

+  This protocol provides a service to set the amount of time to wait

+  before firing the watchdog timer, and it also provides a service to

+  register a handler that is invoked when the watchdog timer fires.

+

+  @par When the watchdog timer fires, control will be passed to a handler

+  if one has been registered.  If no handler has been registered,

+  or the registered handler returns, then the system will be

+  reset by calling the Runtime Service ResetSystem().

+

+  @param RegisterHandler

+  Registers a handler that will be called each time the

+  watchdogtimer interrupt fires.  TimerPeriod defines the minimum

+  time between timer interrupts, so TimerPeriod will also

+  be the minimum time between calls to the registered

+  handler.

+  NOTE: If the watchdog resets the system in hardware, then

+        this function will not have any chance of executing.

+

+  @param SetTimerPeriod

+  Sets the period of the timer interrupt in 100 nS units.

+  This function is optional, and may return EFI_UNSUPPORTED.

+  If this function is supported, then the timer period will

+  be rounded up to the nearest supported timer period.

+

+  @param GetTimerPeriod

+  Retrieves the period of the timer interrupt in 100 nS units.

+

+**/

+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL    gWatchdogTimer = {

+  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) WatchdogRegisterHandler,

+  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) WatchdogSetTimerPeriod,

+  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) WatchdogGetTimerPeriod

+};

+

+EFI_EVENT                           EfiExitBootServicesEvent = (EFI_EVENT)NULL;

+

+EFI_STATUS

+EFIAPI

+GenericWatchdogEntry (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_STATUS                      Status;

+  EFI_HANDLE                      Handle;

+

+  //

+  // Make sure the Watchdog Timer Architectural Protocol has not been installed

+  // in the system yet.

+  // This will avoid conflicts with the universal watchdog

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);

+

+  mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();

+  ASSERT (mTimerFrequencyHz != 0);

+

+  // Register for an ExitBootServicesEvent

+  Status = gBS->CreateEvent (

+                  EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,

+                  WatchdogExitBootServicesEvent, NULL, &EfiExitBootServicesEvent

+                  );

+  if (!EFI_ERROR (Status)) {

+    // Install interrupt handler

+    Status = gBS->LocateProtocol (

+                    &gHardwareInterruptProtocolGuid,

+                    NULL,

+                    (VOID **)&mInterruptProtocol

+                    );

+    if (!EFI_ERROR (Status)) {

+      Status = mInterruptProtocol->RegisterInterruptSource (

+                                    mInterruptProtocol,

+                                    FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),

+                                    WatchdogInterruptHandler

+                                    );

+      if (!EFI_ERROR (Status)) {

+        // Install the Timer Architectural Protocol onto a new handle

+        Handle = NULL;

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &Handle,

+                        &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,

+                        NULL

+                        );

+      }

+    }

+  }

+

+  if (EFI_ERROR (Status)) {

+    // The watchdog failed to initialize

+    ASSERT (FALSE);

+  }

+

+  mNumTimerTicks = 0;

+  WatchdogDisable ();

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
new file mode 100644
index 0000000..fece14c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
@@ -0,0 +1,53 @@
+#

+#  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.

+#

+

+[Defines]

+  INF_VERSION                    = 0x00010016

+  BASE_NAME                      = GenericWatchdogDxe

+  FILE_GUID                      = 0619f5c2-4858-4caa-a86a-73a21a18df6b

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = GenericWatchdogEntry

+

+[Sources.common]

+  GenericWatchdogDxe.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  ArmGenericTimerCounterLib

+  BaseLib

+  BaseMemoryLib

+  DebugLib

+  IoLib

+  PcdLib

+  UefiLib

+  UefiBootServicesTableLib

+  UefiDriverEntryPoint

+  UefiRuntimeServicesTableLib

+

+[Pcd.common]

+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase

+  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase

+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum

+

+[Protocols]

+  gEfiWatchdogTimerArchProtocolGuid

+  gHardwareInterruptProtocolGuid

+

+[Depex]

+  gHardwareInterruptProtocolGuid

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.c
new file mode 100644
index 0000000..d0a819f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.c
@@ -0,0 +1,428 @@
+/** @file

+  Timer Architecture Protocol driver of the ARM flavor

+

+  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/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/PcdLib.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGenericTimerCounterLib.h>

+#include <Library/ArmArchTimer.h>

+

+#include <Protocol/Timer.h>

+#include <Protocol/HardwareInterrupt.h>

+

+// The notification function to call on every timer interrupt.

+EFI_TIMER_NOTIFY      mTimerNotifyFunction     = (EFI_TIMER_NOTIFY)NULL;

+EFI_EVENT             EfiExitBootServicesEvent = (EFI_EVENT)NULL;

+

+// The current period of the timer interrupt

+UINT64 mTimerPeriod = 0;

+// The latest Timer Tick calculated for mTimerPeriod

+UINT64 mTimerTicks = 0;

+// Number of elapsed period since the last Timer interrupt

+UINT64 mElapsedPeriod = 1;

+

+// Cached copy of the Hardware Interrupt protocol instance

+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;

+

+/**

+  This function registers the handler NotifyFunction so it is called every time

+  the timer interrupt fires.  It also passes the amount of time since the last

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is

+  returned.  If the CPU does not support registering a timer interrupt handler,

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.

+  If an attempt is made to unregister a handler when a handler is not registered,

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR

+  is returned.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  NotifyFunction   The function to call when a timer interrupt fires. This

+                           function executes at TPL_HIGH_LEVEL. The DXE Core will

+                           register a handler for the timer interrupt, so it can know

+                           how much time has passed. This information is used to

+                           signal timer based events. NULL will unregister the handler.

+  @retval EFI_SUCCESS           The timer handler was registered.

+  @retval EFI_UNSUPPORTED       The platform does not support timer interrupts.

+  @retval EFI_ALREADY_STARTED   NotifyFunction is not NULL, and a handler is already

+                                registered.

+  @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not

+                                previously registered.

+  @retval EFI_DEVICE_ERROR      The timer handler could not be registered.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  )

+{

+  if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  mTimerNotifyFunction = NotifyFunction;

+

+  return EFI_SUCCESS;

+}

+

+/**

+    Disable the timer

+**/

+VOID

+EFIAPI

+ExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  ArmGenericTimerDisableTimer ();

+}

+

+/**

+

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod      The rate to program the timer interrupt in 100 nS units. If

+                           the timer hardware is not programmable, then EFI_UNSUPPORTED is

+                           returned. If the timer is programmable, then the timer period

+                           will be rounded up to the nearest timer period that is supported

+                           by the timer hardware. If TimerPeriod is set to 0, then the

+                           timer interrupts will be disabled.

+

+

+  @retval EFI_SUCCESS           The timer period was changed.

+  @retval EFI_UNSUPPORTED       The platform cannot change the period of the timer interrupt.

+  @retval EFI_DEVICE_ERROR      The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+{

+  UINT64      CounterValue;

+  UINT64      TimerTicks;

+  EFI_TPL     OriginalTPL;

+

+  // Always disable the timer

+  ArmGenericTimerDisableTimer ();

+

+  if (TimerPeriod != 0) {

+    // mTimerTicks = TimerPeriod in 1ms unit x Frequency.10^-3

+    //             = TimerPeriod.10^-4 x Frequency.10^-3

+    //             = (TimerPeriod x Frequency) x 10^-7

+    TimerTicks = MultU64x32 (TimerPeriod, ArmGenericTimerGetTimerFreq ());

+    TimerTicks = DivU64x32 (TimerTicks, 10000000U);

+

+    // Raise TPL to update the mTimerTicks and mTimerPeriod to ensure these values

+    // are coherent in the interrupt handler

+    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+

+    mTimerTicks    = TimerTicks;

+    mTimerPeriod   = TimerPeriod;

+    mElapsedPeriod = 1;

+

+    gBS->RestoreTPL (OriginalTPL);

+

+    // Get value of the current timer

+    CounterValue = ArmGenericTimerGetSystemCount ();

+    // Set the interrupt in Current Time + mTimerTick

+    ArmGenericTimerSetCompareVal (CounterValue + mTimerTicks);

+

+    // Enable the timer

+    ArmGenericTimerEnableTimer ();

+  } else {

+    // Save the new timer period

+    mTimerPeriod   = TimerPeriod;

+    // Reset the elapsed period

+    mElapsedPeriod = 1;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod      A pointer to the timer period to retrieve in 100 ns units. If

+                           0 is returned, then the timer is currently disabled.

+

+

+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.

+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  )

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = mTimerPeriod;

+  return EFI_SUCCESS;

+}

+

+/**

+  This function generates a soft timer interrupt. If the platform does not support soft

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()

+  service, then a soft timer interrupt will be generated. If the timer interrupt is

+  enabled when this service is called, then the registered handler will be invoked. The

+  registered handler should not be able to distinguish a hardware-generated timer

+  interrupt from a software-generated timer interrupt.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           The soft timer interrupt was generated.

+  @retval EFI_UNSUPPORTED       The platform does not support the generation of soft timer interrupts.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  Interface structure for the Timer Architectural Protocol.

+

+  @par Protocol Description:

+  This protocol provides the services to initialize a periodic timer

+  interrupt, and to register a handler that is called each time the timer

+  interrupt fires.  It may also provide a service to adjust the rate of the

+  periodic timer interrupt.  When a timer interrupt occurs, the handler is

+  passed the amount of time that has passed since the previous timer

+  interrupt.

+

+  @param RegisterHandler

+  Registers a handler that will be called each time the

+  timer interrupt fires.  TimerPeriod defines the minimum

+  time between timer interrupts, so TimerPeriod will also

+  be the minimum time between calls to the registered

+  handler.

+

+  @param SetTimerPeriod

+  Sets the period of the timer interrupt in 100 nS units.

+  This function is optional, and may return EFI_UNSUPPORTED.

+  If this function is supported, then the timer period will

+  be rounded up to the nearest supported timer period.

+

+

+  @param GetTimerPeriod

+  Retrieves the period of the timer interrupt in 100 nS units.

+

+  @param GenerateSoftInterrupt

+  Generates a soft timer interrupt that simulates the firing of

+  the timer interrupt. This service can be used to invoke the   registered handler if the timer interrupt has been masked for

+  a period of time.

+

+**/

+EFI_TIMER_ARCH_PROTOCOL   gTimer = {

+  TimerDriverRegisterHandler,

+  TimerDriverSetTimerPeriod,

+  TimerDriverGetTimerPeriod,

+  TimerDriverGenerateSoftInterrupt

+};

+

+/**

+

+  C Interrupt Handler called in the interrupt context when Source interrupt is active.

+

+

+  @param Source         Source of the interrupt. Hardware routing off a specific platform defines

+                        what source means.

+

+  @param SystemContext  Pointer to system register context. Mostly used by debuggers and will

+                        update the system context after the return from the interrupt if

+                        modified. Don't change these values unless you know what you are doing

+

+**/

+VOID

+EFIAPI

+TimerInterruptHandler (

+  IN  HARDWARE_INTERRUPT_SOURCE   Source,

+  IN  EFI_SYSTEM_CONTEXT          SystemContext

+  )

+{

+  EFI_TPL      OriginalTPL;

+  UINT64       CurrentValue;

+  UINT64       CompareValue;

+

+  //

+  // DXE core uses this callback for the EFI timer tick. The DXE core uses locks

+  // that raise to TPL_HIGH and then restore back to current level. Thus we need

+  // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.

+  //

+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+

+  // Check if the timer interrupt is active

+  if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {

+

+    // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers

+    gInterrupt->EndOfInterrupt (gInterrupt, Source);

+

+    if (mTimerNotifyFunction) {

+      mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);

+    }

+

+    //

+    // Reload the Timer

+    //

+

+    // Get current counter value

+    CurrentValue = ArmGenericTimerGetSystemCount ();

+    // Get the counter value to compare with

+    CompareValue = ArmGenericTimerGetCompareVal ();

+

+    // This loop is needed in case we missed interrupts (eg: case when the interrupt handling

+    // has taken longer than mTickPeriod).

+    // Note: Physical Counter is counting up

+    mElapsedPeriod = 0;

+    do {

+      CompareValue += mTimerTicks;

+      mElapsedPeriod++;

+    } while (CompareValue < CurrentValue);

+

+    // Set next compare value

+    ArmGenericTimerSetCompareVal (CompareValue);

+    ArmGenericTimerEnableTimer ();

+  }

+

+  // Enable timer interrupts

+  gInterrupt->EnableInterruptSource (gInterrupt, Source);

+

+  gBS->RestoreTPL (OriginalTPL);

+}

+

+

+/**

+  Initialize the state information for the Timer Architectural Protocol and

+  the Timer Debug support protocol that allows the debugger to break into a

+  running program.

+

+  @param  ImageHandle   of the loaded driver

+  @param  SystemTable   Pointer to the System Table

+

+  @retval EFI_SUCCESS           Protocol registered

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Hardware problems

+

+**/

+EFI_STATUS

+EFIAPI

+TimerInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_HANDLE  Handle = NULL;

+  EFI_STATUS  Status;

+  UINTN TimerCtrlReg;

+

+  if (ArmIsArchTimerImplemented () == 0) {

+    DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));

+    ASSERT (0);

+  }

+

+  // Find the interrupt controller protocol.  ASSERT if not found.

+  Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);

+  ASSERT_EFI_ERROR (Status);

+

+  // Disable the timer

+  TimerCtrlReg = ArmGenericTimerGetTimerCtrlReg ();

+  TimerCtrlReg |= ARM_ARCH_TIMER_IMASK;

+  TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;

+  ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg);

+  Status = TimerDriverSetTimerPeriod (&gTimer, 0);

+  ASSERT_EFI_ERROR (Status);

+

+  // Install secure and Non-secure interrupt handlers

+  // Note: Because it is not possible to determine the security state of the

+  // CPU dynamically, we just install interrupt handler for both sec and non-sec

+  // timer PPI

+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerHypIntrNum), TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+

+  // Set up default timer

+  Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD

+  ASSERT_EFI_ERROR (Status);

+

+  // Install the Timer Architectural Protocol onto a new handle

+  Status = gBS->InstallMultipleProtocolInterfaces(

+                  &Handle,

+                  &gEfiTimerArchProtocolGuid,      &gTimer,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR(Status);

+

+  // Everything is ready, unmask and enable timer interrupts

+  TimerCtrlReg = ARM_ARCH_TIMER_ENABLE;

+  ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg);

+

+  // Register for an ExitBootServicesEvent

+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.inf
new file mode 100644
index 0000000..3f34515
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.inf
@@ -0,0 +1,60 @@
+#/** @file

+#

+#    Component description file for Timer DXE module

+#

+#  Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmTimerDxe

+  FILE_GUID                      = 49ea041e-6752-42ca-b0b1-7344fe2546b7

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = TimerInitialize

+

+[Sources.common]

+  TimerDxe.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  BaseLib

+  UefiRuntimeServicesTableLib

+  UefiLib

+  UefiBootServicesTableLib

+  BaseMemoryLib

+  DebugLib

+  UefiDriverEntryPoint

+  IoLib

+  ArmGenericTimerCounterLib

+

+[Guids]

+

+[Protocols]

+  gEfiTimerArchProtocolGuid

+  gHardwareInterruptProtocolGuid

+

+[Pcd.common]

+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod

+  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum

+  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum

+  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum

+  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum

+

+[Depex]

+  gHardwareInterruptProtocolGuid

diff --git a/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
new file mode 100644
index 0000000..6efdad9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
@@ -0,0 +1,1205 @@
+/** @file

+  Support a Semi Host file system over a debuggers JTAG

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Portions 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 <Uefi.h>

+

+#include <Guid/FileInfo.h>

+#include <Guid/FileSystemInfo.h>

+#include <Guid/FileSystemVolumeLabelInfo.h>

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/SemihostLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+

+#include <Protocol/DevicePath.h>

+#include <Protocol/SimpleFileSystem.h>

+

+#include "SemihostFs.h"

+

+#define DEFAULT_SEMIHOST_FS_LABEL   L"SemihostFs"

+

+STATIC CHAR16 *mSemihostFsLabel;

+

+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,

+  VolumeOpen

+};

+

+EFI_FILE gSemihostFsFile = {

+  EFI_FILE_PROTOCOL_REVISION,

+  FileOpen,

+  FileClose,

+  FileDelete,

+  FileRead,

+  FileWrite,

+  FileGetPosition,

+  FileSetPosition,

+  FileGetInfo,

+  FileSetInfo,

+  FileFlush

+};

+

+//

+// Device path for semi-hosting. It contains our autogened Caller ID GUID.

+//

+typedef struct {

+  VENDOR_DEVICE_PATH        Guid;

+  EFI_DEVICE_PATH_PROTOCOL  End;

+} SEMIHOST_DEVICE_PATH;

+

+SEMIHOST_DEVICE_PATH gDevicePath = {

+  {

+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },

+    EFI_CALLER_ID_GUID

+  },

+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }

+};

+

+typedef struct {

+  LIST_ENTRY    Link;

+  UINT64        Signature;

+  EFI_FILE      File;

+  CHAR8         *FileName;

+  UINT64        OpenMode;

+  UINT32        Position;

+  UINTN         SemihostHandle;

+  BOOLEAN       IsRoot;

+  EFI_FILE_INFO Info;

+} SEMIHOST_FCB;

+

+#define SEMIHOST_FCB_SIGNATURE      SIGNATURE_32( 'S', 'H', 'F', 'C' )

+#define SEMIHOST_FCB_FROM_THIS(a)   CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)

+#define SEMIHOST_FCB_FROM_LINK(a)   CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);

+

+EFI_HANDLE  gInstallHandle = NULL;

+LIST_ENTRY  gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList);

+

+SEMIHOST_FCB *

+AllocateFCB (

+  VOID

+  )

+{

+  SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));

+

+  if (Fcb != NULL) {

+    CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));

+    Fcb->Signature = SEMIHOST_FCB_SIGNATURE;

+  }

+

+  return Fcb;

+}

+

+VOID

+FreeFCB (

+  IN SEMIHOST_FCB *Fcb

+  )

+{

+  // Remove Fcb from gFileList.

+  RemoveEntryList (&Fcb->Link);

+

+  // To help debugging...

+  Fcb->Signature = 0;

+

+  FreePool (Fcb);

+}

+

+

+

+EFI_STATUS

+VolumeOpen (

+  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,

+  OUT EFI_FILE                        **Root

+  )

+{

+  SEMIHOST_FCB *RootFcb = NULL;

+

+  if (Root == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  RootFcb = AllocateFCB ();

+  if (RootFcb == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  RootFcb->IsRoot = TRUE;

+  RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;

+

+  InsertTailList (&gFileList, &RootFcb->Link);

+

+  *Root = &RootFcb->File;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Open a file on the host system by means of the semihosting interface.

+

+  @param[in]   This        A pointer to the EFI_FILE_PROTOCOL instance that is

+                           the file handle to source location.

+  @param[out]  NewHandle   A pointer to the location to return the opened

+                           handle for the new file.

+  @param[in]   FileName    The Null-terminated string of the name of the file

+                           to be opened.

+  @param[in]   OpenMode    The mode to open the file : Read or Read/Write or

+                           Read/Write/Create

+  @param[in]   Attributes  Only valid for EFI_FILE_MODE_CREATE, in which case these

+                           are the attribute bits for the newly created file. The

+                           mnemonics of the attribute bits are : EFI_FILE_READ_ONLY,

+                           EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED,

+                           EFI_FILE_DIRECTORY and EFI_FILE_ARCHIVE.

+

+  @retval  EFI_SUCCESS            The file was open.

+  @retval  EFI_NOT_FOUND          The specified file could not be found.

+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.

+  @retval  EFI_WRITE_PROTECTED    Attempt to create a directory. This is not possible

+                                  with the semi-hosting interface.

+  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to open the file.

+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

+

+**/

+EFI_STATUS

+FileOpen (

+  IN  EFI_FILE  *This,

+  OUT EFI_FILE  **NewHandle,

+  IN  CHAR16    *FileName,

+  IN  UINT64    OpenMode,

+  IN  UINT64    Attributes

+  )

+{

+  SEMIHOST_FCB   *FileFcb;

+  RETURN_STATUS  Return;

+  EFI_STATUS     Status;

+  UINTN          SemihostHandle;

+  CHAR8          *AsciiFileName;

+  UINT32         SemihostMode;

+  UINTN          Length;

+

+  if ((FileName == NULL) || (NewHandle == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ( (OpenMode != EFI_FILE_MODE_READ) &&

+       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&

+       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((OpenMode & EFI_FILE_MODE_CREATE) &&

+      (Attributes & EFI_FILE_DIRECTORY)    ) {

+    return EFI_WRITE_PROTECTED;

+  }

+

+  AsciiFileName = AllocatePool (StrLen (FileName) + 1);

+  if (AsciiFileName == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  UnicodeStrToAsciiStr (FileName, AsciiFileName);

+

+  // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory

+  if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||

+      (AsciiStrCmp (AsciiFileName, "/")  == 0) ||

+      (AsciiStrCmp (AsciiFileName, "")   == 0) ||

+      (AsciiStrCmp (AsciiFileName, ".")  == 0)    ) {

+    FreePool (AsciiFileName);

+    return (VolumeOpen (&gSemihostFs, NewHandle));

+  }

+

+  //

+  // No control is done here concerning the file path. It is passed

+  // as it is to the host operating system through the semi-hosting

+  // interface. We first try to open the file in the read or update

+  // mode even if the file creation has been asked for. That way, if

+  // the file already exists, it is not truncated to zero length. In

+  // write mode (bit SEMIHOST_FILE_MODE_WRITE up), if the file already

+  // exists, it is reset to an empty file.

+  //

+  if (OpenMode == EFI_FILE_MODE_READ) {

+    SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY;

+  } else {

+    SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;

+  }

+  Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);

+

+  if (RETURN_ERROR (Return)) {

+    if (OpenMode & EFI_FILE_MODE_CREATE) {

+      //

+      // In the create if does not exist case, if the opening in update

+      // mode failed, create it and open it in update mode. The update

+      // mode allows for both read and write from and to the file.

+      //

+      Return = SemihostFileOpen (

+                 AsciiFileName,

+                 SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE,

+                 &SemihostHandle

+                 );

+      if (RETURN_ERROR (Return)) {

+        Status = EFI_DEVICE_ERROR;

+        goto Error;

+      }

+    } else {

+      Status = EFI_NOT_FOUND;

+      goto Error;

+    }

+  }

+

+  // Allocate a control block and fill it

+  FileFcb = AllocateFCB ();

+  if (FileFcb == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+

+  FileFcb->FileName       = AsciiFileName;

+  FileFcb->SemihostHandle = SemihostHandle;

+  FileFcb->Position       = 0;

+  FileFcb->IsRoot         = 0;

+  FileFcb->OpenMode       = OpenMode;

+

+  Return = SemihostFileLength (SemihostHandle, &Length);

+  if (RETURN_ERROR (Return)) {

+    Status = EFI_DEVICE_ERROR;

+    FreeFCB (FileFcb);

+    goto Error;

+  }

+

+  FileFcb->Info.FileSize     = Length;

+  FileFcb->Info.PhysicalSize = Length;

+  FileFcb->Info.Attribute    = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0;

+

+  InsertTailList (&gFileList, &FileFcb->Link);

+

+  *NewHandle = &FileFcb->File;

+

+  return EFI_SUCCESS;

+

+Error:

+

+  FreePool (AsciiFileName);

+

+  return Status;

+}

+

+/**

+  Worker function that truncate a file specified by its name to a given size.

+

+  @param[in]  FileName  The Null-terminated string of the name of the file to be opened.

+  @param[in]  Size      The target size for the file.

+

+  @retval  EFI_SUCCESS       The file was truncated.

+  @retval  EFI_DEVICE_ERROR  The last issued semi-hosting operation failed.

+

+**/

+STATIC

+EFI_STATUS

+TruncateFile (

+  IN CHAR8  *FileName,

+  IN UINTN   Size

+  )

+{

+  EFI_STATUS     Status;

+  RETURN_STATUS  Return;

+  UINTN          FileHandle;

+  UINT8          *Buffer;

+  UINTN          Remaining;

+  UINTN          Read;

+  UINTN          ToRead;

+

+  Status     = EFI_DEVICE_ERROR;

+  FileHandle = 0;

+  Buffer     = NULL;

+

+  Return = SemihostFileOpen (

+             FileName,

+             SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,

+             &FileHandle

+             );

+  if (RETURN_ERROR (Return)) {

+    goto Error;

+  }

+

+  Buffer = AllocatePool (Size);

+  if (Buffer == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+

+  Read = 0;

+  Remaining = Size;

+  while (Remaining > 0) {

+    ToRead = Remaining;

+    Return = SemihostFileRead (FileHandle, &ToRead, Buffer + Read);

+    if (RETURN_ERROR (Return)) {

+      goto Error;

+    }

+    Remaining -= ToRead;

+    Read      += ToRead;

+  }

+

+  Return = SemihostFileClose (FileHandle);

+  FileHandle = 0;

+  if (RETURN_ERROR (Return)) {

+    goto Error;

+  }

+

+  Return = SemihostFileOpen (

+             FileName,

+             SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY,

+             &FileHandle

+             );

+  if (RETURN_ERROR (Return)) {

+    goto Error;

+  }

+

+  if (Size > 0) {

+    Return = SemihostFileWrite (FileHandle, &Size, Buffer);

+    if (RETURN_ERROR (Return)) {

+      goto Error;

+    }

+  }

+

+  Status = EFI_SUCCESS;

+

+Error:

+

+  if (FileHandle != 0) {

+    SemihostFileClose (FileHandle);

+  }

+  if (Buffer != NULL) {

+    FreePool (Buffer);

+  }

+

+  return (Status);

+

+}

+

+/**

+  Close a specified file handle.

+

+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file

+                    handle to close.

+

+  @retval  EFI_SUCCESS            The file was closed.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" is NULL.

+

+**/

+EFI_STATUS

+FileClose (

+  IN EFI_FILE  *This

+  )

+{

+  SEMIHOST_FCB   *Fcb;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS(This);

+

+  if (!Fcb->IsRoot) {

+    SemihostFileClose (Fcb->SemihostHandle);

+    //

+    // The file size might have been reduced from its actual

+    // size on the host file system with FileSetInfo(). In

+    // that case, the file has to be truncated.

+    //

+    if (Fcb->Info.FileSize < Fcb->Info.PhysicalSize) {

+      TruncateFile (Fcb->FileName, Fcb->Info.FileSize);

+    }

+    FreePool (Fcb->FileName);

+  }

+

+  FreeFCB (Fcb);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Close and delete a file.

+

+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file

+                    handle to delete.

+

+  @retval  EFI_SUCCESS              The file was closed and deleted.

+  @retval  EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.

+  @retval  EFI_INVALID_PARAMETER    The parameter "This" is NULL.

+

+**/

+EFI_STATUS

+FileDelete (

+  IN EFI_FILE *This

+  )

+{

+  SEMIHOST_FCB   *Fcb;

+  RETURN_STATUS  Return;

+  CHAR8          *FileName;

+  UINTN          NameSize;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS (This);

+

+  if (!Fcb->IsRoot) {

+    // Get the filename from the Fcb

+    NameSize = AsciiStrLen (Fcb->FileName);

+    FileName = AllocatePool (NameSize + 1);

+

+    AsciiStrCpy (FileName, Fcb->FileName);

+

+    // Close the file if it's open.  Disregard return status,

+    // since it might give an error if the file isn't open.

+    This->Close (This);

+

+    // Call the semihost interface to delete the file.

+    Return = SemihostFileRemove (FileName);

+    if (RETURN_ERROR (Return)) {

+      return EFI_WARN_DELETE_FAILURE;

+    }

+    return EFI_SUCCESS;

+  } else {

+    return EFI_WARN_DELETE_FAILURE;

+  }

+}

+

+/**

+  Read data from an open file.

+

+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that

+                              is the file handle to read data from.

+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the

+                              amount of data returned in Buffer. In both cases,

+                              the size is measured in bytes.

+  @param[out]     Buffer      The buffer into which the data is read.

+

+  @retval  EFI_SUCCESS            The data was read.

+  @retval  EFI_DEVICE_ERROR       On entry, the current file position is

+                                  beyond the end of the file, or the semi-hosting

+                                  interface reported an error while performing the

+                                  read operation.

+  @retval  EFI_INVALID_PARAMETER  At least one of the three input pointers is NULL.

+

+**/

+EFI_STATUS

+FileRead (

+  IN     EFI_FILE  *This,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  )

+{

+  SEMIHOST_FCB   *Fcb;

+  EFI_STATUS     Status;

+  RETURN_STATUS  Return;

+

+  if ((This == NULL) || (BufferSize == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS (This);

+

+  if (Fcb->IsRoot) {

+    // The semi-hosting interface does not allow to list files on the host machine.

+    Status = EFI_UNSUPPORTED;

+  } else {

+    Status = EFI_SUCCESS;

+    if (Fcb->Position >= Fcb->Info.FileSize) {

+      *BufferSize = 0;

+      if (Fcb->Position > Fcb->Info.FileSize) {

+        Status = EFI_DEVICE_ERROR;

+      }

+    } else {

+      Return = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer);

+      if (RETURN_ERROR (Return)) {

+        Status = EFI_DEVICE_ERROR;

+      } else {

+        Fcb->Position += *BufferSize;

+      }

+    }

+  }

+

+  return Status;

+}

+

+/**

+  Worker function that extends the size of an open file.

+

+  The extension is filled with zeros.

+

+  @param[in]  Fcb   Internal description of the opened file

+  @param[in]  Size  The number of bytes, the file has to be extended.

+

+  @retval  EFI_SUCCESS       The file was extended.

+  @retval  EFI_DEVICE_ERROR  The last issued semi-hosting operation failed.

+

+**/

+STATIC

+EFI_STATUS

+ExtendFile (

+  IN  SEMIHOST_FCB  *Fcb,

+  IN  UINTN         Size

+  )

+{

+  RETURN_STATUS  Return;

+  UINTN          Remaining;

+  CHAR8          WriteBuffer[128];

+  UINTN          WriteNb;

+  UINTN          WriteSize;

+

+  Return = SemihostFileSeek (Fcb->SemihostHandle, Fcb->Info.FileSize);

+  if (RETURN_ERROR (Return)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Remaining = Size;

+  SetMem (WriteBuffer, 0, sizeof(WriteBuffer));

+  while (Remaining > 0) {

+    WriteNb = MIN (Remaining, sizeof(WriteBuffer));

+    WriteSize = WriteNb;

+    Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);

+    if (RETURN_ERROR (Return)) {

+      return EFI_DEVICE_ERROR;

+    }

+    Remaining -= WriteNb;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Write data to an open file.

+

+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that

+                              is the file handle to write data to.

+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the

+                              size of the data actually written. In both cases,

+                              the size is measured in bytes.

+  @param[in]      Buffer      The buffer of data to write.

+

+  @retval  EFI_SUCCESS            The data was written.

+  @retval  EFI_ACCESS_DENIED      Attempt to write into a read only file or

+                                  in a file opened in read only mode.

+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.

+  @retval  EFI_INVALID_PARAMETER  At least one of the three input pointers is NULL.

+

+**/

+EFI_STATUS

+FileWrite (

+  IN     EFI_FILE *This,

+  IN OUT UINTN    *BufferSize,

+  IN     VOID     *Buffer

+  )

+{

+  SEMIHOST_FCB   *Fcb;

+  EFI_STATUS     Status;

+  UINTN          WriteSize;

+  RETURN_STATUS  Return;

+  UINTN          Length;

+

+  if ((This == NULL) || (BufferSize == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS (This);

+

+  // We cannot write a read-only file

+  if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)

+      || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  //

+  // If the position has been set past the end of the file, first grow the

+  // file from its current size "Fcb->Info.FileSize" to "Fcb->Position"

+  // size, filling the gap with zeros.

+  //

+  if (Fcb->Position > Fcb->Info.FileSize) {

+    Status = ExtendFile (Fcb, Fcb->Position - Fcb->Info.FileSize);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    Fcb->Info.FileSize = Fcb->Position;

+  }

+

+  WriteSize = *BufferSize;

+  Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);

+  if (RETURN_ERROR (Return)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  Fcb->Position += *BufferSize;

+  if (Fcb->Position > Fcb->Info.FileSize) {

+    Fcb->Info.FileSize = Fcb->Position;

+  }

+

+  Return = SemihostFileLength (Fcb->SemihostHandle, &Length);

+  if (RETURN_ERROR (Return)) {

+    return EFI_DEVICE_ERROR;

+  }

+  Fcb->Info.PhysicalSize = Length;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return a file's current position.

+

+  @param[in]   This      A pointer to the EFI_FILE_PROTOCOL instance that is

+                         the file handle to get the current position on.

+  @param[out]  Position  The address to return the file's current position value.

+

+  @retval  EFI_SUCCESS            The position was returned.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" or "Position" is NULL.

+

+**/

+EFI_STATUS

+FileGetPosition (

+  IN  EFI_FILE    *This,

+  OUT UINT64      *Position

+  )

+{

+  SEMIHOST_FCB *Fcb;

+

+  if ((This == NULL) || (Position == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS(This);

+

+  *Position = Fcb->Position;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Set a file's current position.

+

+  @param[in]  This      A pointer to the EFI_FILE_PROTOCOL instance that is

+                        the file handle to set the requested position on.

+  @param[in]  Position  The byte position from the start of the file to set.

+

+  @retval  EFI_SUCCESS       The position was set.

+  @retval  EFI_DEVICE_ERROR  The semi-hosting positionning operation failed.

+  @retval  EFI_UNSUPPORTED   The seek request for nonzero is not valid on open

+                             directories.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" is NULL.

+

+**/

+EFI_STATUS

+FileSetPosition (

+  IN EFI_FILE *This,

+  IN UINT64   Position

+  )

+{

+  SEMIHOST_FCB   *Fcb;

+  RETURN_STATUS  Return;

+

+  if (This == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS (This);

+

+  if (Fcb->IsRoot) {

+    if (Position != 0) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  else {

+    //

+    // UEFI Spec section 12.5:

+    // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to

+    // be set to the end of the file."

+    //

+    if (Position == 0xFFFFFFFFFFFFFFFF) {

+      Position = Fcb->Info.FileSize;

+    }

+    Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize));

+    if (RETURN_ERROR (Return)) {

+      return EFI_DEVICE_ERROR;

+    }

+  }

+

+  Fcb->Position = Position;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return information about a file.

+

+  @param[in]      Fcb         A pointer to the description of an open file.

+  @param[in out]  BufferSize  The size, in bytes, of Buffer.

+  @param[out]     Buffer      A pointer to the data buffer to return. Not NULL if

+                              "*BufferSize" is greater than 0.

+

+  @retval  EFI_SUCCESS            The information was returned.

+  @retval  EFI_BUFFER_TOO_SMALL   The BufferSize is too small to return the information.

+                                  BufferSize has been updated with the size needed to

+                                  complete the request.

+**/

+STATIC

+EFI_STATUS

+GetFileInfo (

+  IN     SEMIHOST_FCB  *Fcb,

+  IN OUT UINTN         *BufferSize,

+  OUT    VOID          *Buffer

+  )

+{

+  EFI_FILE_INFO   *Info = NULL;

+  UINTN           NameSize = 0;

+  UINTN           ResultSize;

+  UINTN           Index;

+

+  if (Fcb->IsRoot == TRUE) {

+    ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);

+  } else {

+    NameSize   = AsciiStrLen (Fcb->FileName) + 1;

+    ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);

+  }

+

+  if (*BufferSize < ResultSize) {

+    *BufferSize = ResultSize;

+    return EFI_BUFFER_TOO_SMALL;

+  }

+

+  Info = Buffer;

+

+  // Copy the current file info

+  CopyMem (Info, &Fcb->Info, SIZE_OF_EFI_FILE_INFO);

+

+  // Fill in the structure

+  Info->Size = ResultSize;

+

+  if (Fcb->IsRoot == TRUE) {

+    Info->FileName[0]  = L'\0';

+  } else {

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

+      Info->FileName[Index] = Fcb->FileName[Index];

+    }

+  }

+

+  *BufferSize = ResultSize;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return information about a file system.

+

+  @param[in]      Fcb         A pointer to the description of an open file

+                              which belongs to the file system, the information

+                              is requested for.

+  @param[in out]  BufferSize  The size, in bytes, of Buffer.

+  @param[out]     Buffer      A pointer to the data buffer to return. Not NULL if

+                              "*BufferSize" is greater than 0.

+

+  @retval  EFI_SUCCESS            The information was returned.

+  @retval  EFI_BUFFER_TOO_SMALL   The BufferSize is too small to return the information.

+                                  BufferSize has been updated with the size needed to

+                                  complete the request.

+

+**/

+STATIC

+EFI_STATUS

+GetFilesystemInfo (

+  IN     SEMIHOST_FCB *Fcb,

+  IN OUT UINTN        *BufferSize,

+  OUT    VOID         *Buffer

+  )

+{

+  EFI_FILE_SYSTEM_INFO  *Info;

+  EFI_STATUS            Status;

+  UINTN                 ResultSize;

+

+  ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (mSemihostFsLabel);

+

+  if (*BufferSize >= ResultSize) {

+    ZeroMem (Buffer, ResultSize);

+    Status = EFI_SUCCESS;

+

+    Info = Buffer;

+

+    Info->Size       = ResultSize;

+    Info->ReadOnly   = FALSE;

+    Info->VolumeSize = 0;

+    Info->FreeSpace  = 0;

+    Info->BlockSize  = 0;

+

+    StrCpy (Info->VolumeLabel, mSemihostFsLabel);

+  } else {

+    Status = EFI_BUFFER_TOO_SMALL;

+  }

+

+  *BufferSize = ResultSize;

+  return Status;

+}

+

+/**

+  Return information about a file or a file system.

+

+  @param[in]      This             A pointer to the EFI_FILE_PROTOCOL instance that

+                                   is the file handle the requested information is for.

+  @param[in]      InformationType  The type identifier for the information being requested :

+                                   EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or

+                                   EFI_FILE_SYSTEM_VOLUME_LABEL_ID

+  @param[in out]  BufferSize       The size, in bytes, of Buffer.

+  @param[out]     Buffer           A pointer to the data buffer to return. The type of the

+                                   data inside the buffer is indicated by InformationType.

+

+  @retval  EFI_SUCCESS           The information was returned.

+  @retval  EFI_UNSUPPORTED       The InformationType is not known.

+  @retval  EFI_BUFFER_TOO_SMALL  The BufferSize is too small to return the information.

+                                 BufferSize has been updated with the size needed to

+                                 complete the request.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" or "InformationType" or "BufferSize"

+                                  is NULL or "Buffer" is NULL and "*Buffersize" is greater

+                                  than 0.

+

+**/

+EFI_STATUS

+FileGetInfo (

+  IN     EFI_FILE  *This,

+  IN     EFI_GUID  *InformationType,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  )

+{

+  SEMIHOST_FCB *Fcb;

+  EFI_STATUS   Status;

+  UINTN        ResultSize;

+

+  if ((This == NULL)                         ||

+      (InformationType == NULL)              ||

+      (BufferSize == NULL)                   ||

+      ((Buffer == NULL) && (*BufferSize > 0))  ) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS(This);

+

+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {

+    Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);

+  } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {

+    Status = GetFileInfo (Fcb, BufferSize, Buffer);

+  } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {

+    ResultSize = StrSize (mSemihostFsLabel);

+

+    if (*BufferSize >= ResultSize) {

+      StrCpy (Buffer, mSemihostFsLabel);

+      Status = EFI_SUCCESS;

+    } else {

+      Status = EFI_BUFFER_TOO_SMALL;

+    }

+

+    *BufferSize = ResultSize;

+  } else {

+    Status = EFI_UNSUPPORTED;

+  }

+

+  return Status;

+}

+

+/**

+  Set information about a file.

+

+  @param[in]  Fcb   A pointer to the description of the open file.

+  @param[in]  Info  A pointer to the file information to write.

+

+  @retval  EFI_SUCCESS           The information was set.

+  @retval  EFI_ACCESS_DENIED     An attempt is made to change the name of a file

+                                 to a file that is already present.

+  @retval  EFI_ACCESS_DENIED     An attempt is being made to change the

+                                 EFI_FILE_DIRECTORY Attribute.

+  @retval  EFI_ACCESS_DENIED     The file is a read-only file or has been

+                                 opened in read-only mode and an attempt is

+                                 being made to modify a field other than

+                                 Attribute.

+  @retval  EFI_WRITE_PROTECTED   An attempt is being made to modify a

+                                 read-only attribute.

+  @retval  EFI_DEVICE_ERROR      The last issued semi-hosting operation failed.

+  @retval  EFI_OUT_OF_RESOURCES  A allocation needed to process the request failed.

+

+**/

+STATIC

+EFI_STATUS

+SetFileInfo (

+  IN  SEMIHOST_FCB   *Fcb,

+  IN  EFI_FILE_INFO  *Info

+  )

+{

+  EFI_STATUS     Status;

+  RETURN_STATUS  Return;

+  BOOLEAN        FileSizeIsDifferent;

+  BOOLEAN        FileNameIsDifferent;

+  BOOLEAN        ReadOnlyIsDifferent;

+  CHAR8          *AsciiFileName;

+  UINTN          FileSize;

+  UINTN          Length;

+  UINTN          SemihostHandle;

+

+  //

+  // A directory can not be changed to a file and a file can

+  // not be changed to a directory.

+  //

+  if (((Info->Attribute & EFI_FILE_DIRECTORY) != 0) != Fcb->IsRoot) {

+    return EFI_ACCESS_DENIED;

+  }

+

+  AsciiFileName = AllocatePool (StrLen (Info->FileName) + 1);

+  if (AsciiFileName == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  UnicodeStrToAsciiStr (Info->FileName, AsciiFileName);

+

+  FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize);

+  FileNameIsDifferent = (AsciiStrCmp (AsciiFileName, Fcb->FileName) != 0);

+  ReadOnlyIsDifferent = CompareMem (

+                          &Info->CreateTime,

+                          &Fcb->Info.CreateTime,

+                          3 * sizeof (EFI_TIME)

+                          ) != 0;

+

+  //

+  // For a read-only file or a file opened in read-only mode, only

+  // the Attribute field can be modified. As the root directory is

+  // read-only (i.e. VolumeOpen()), this protects the root directory

+  // description.

+  //

+  if ((Fcb->OpenMode == EFI_FILE_MODE_READ)     ||

+      (Fcb->Info.Attribute & EFI_FILE_READ_ONLY)  ) {

+    if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) {

+      Status = EFI_ACCESS_DENIED;

+      goto Error;

+    }

+  }

+

+  if (ReadOnlyIsDifferent) {

+    Status = EFI_WRITE_PROTECTED;

+    goto Error;

+  }

+

+  Status = EFI_DEVICE_ERROR;

+

+  if (FileSizeIsDifferent) {

+    FileSize = Info->FileSize;

+    if (Fcb->Info.FileSize < FileSize) {

+      Status = ExtendFile (Fcb, FileSize - Fcb->Info.FileSize);

+      if (EFI_ERROR (Status)) {

+        goto Error;

+      }

+      //

+      // The read/write position from the host file system point of view

+      // is at the end of the file. If the position from this module

+      // point of view is smaller than the new file size, then

+      // ask the host file system to move to that position.

+      //

+      if (Fcb->Position < FileSize) {

+        FileSetPosition (&Fcb->File, Fcb->Position);

+      }

+    }

+    Fcb->Info.FileSize = FileSize;

+

+    Return = SemihostFileLength (Fcb->SemihostHandle, &Length);

+    if (RETURN_ERROR (Return)) {

+      goto Error;

+    }

+    Fcb->Info.PhysicalSize = Length;

+  }

+

+  //

+  // Note down in RAM the Attribute field but we can not ask

+  // for its modification to the host file system as the

+  // semi-host interface does not provide this feature.

+  //

+  Fcb->Info.Attribute = Info->Attribute;

+

+  if (FileNameIsDifferent) {

+    Return = SemihostFileOpen (

+               AsciiFileName,

+               SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,

+               &SemihostHandle

+               );

+    if (!RETURN_ERROR (Return)) {

+      SemihostFileClose (SemihostHandle);

+      Status = EFI_ACCESS_DENIED;

+      goto Error;

+    }

+

+    Return = SemihostFileRename (Fcb->FileName, AsciiFileName);

+    if (RETURN_ERROR (Return)) {

+      goto Error;

+    }

+    FreePool (Fcb->FileName);

+    Fcb->FileName = AsciiFileName;

+    AsciiFileName = NULL;

+  }

+

+  Status = EFI_SUCCESS;

+

+Error:

+  if (AsciiFileName != NULL) {

+    FreePool (AsciiFileName);

+  }

+

+  return Status;

+}

+

+/**

+  Set information about a file or a file system.

+

+  @param[in]  This             A pointer to the EFI_FILE_PROTOCOL instance that

+                               is the file handle the information is for.

+  @param[in]  InformationType  The type identifier for the information being set :

+                               EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or

+                               EFI_FILE_SYSTEM_VOLUME_LABEL_ID

+  @param[in]  BufferSize       The size, in bytes, of Buffer.

+  @param[in]  Buffer           A pointer to the data buffer to write. The type of the

+                               data inside the buffer is indicated by InformationType.

+

+  @retval  EFI_SUCCESS            The information was set.

+  @retval  EFI_UNSUPPORTED        The InformationType is not known.

+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.

+  @retval  EFI_ACCESS_DENIED      An attempt is being made to change the

+                                  EFI_FILE_DIRECTORY Attribute.

+  @retval  EFI_ACCESS_DENIED      InformationType is EFI_FILE_INFO_ID and

+                                  the file is a read-only file or has been

+                                  opened in read-only mode and an attempt is

+                                  being made to modify a field other than

+                                  Attribute.

+  @retval  EFI_ACCESS_DENIED      An attempt is made to change the name of a file

+                                  to a file that is already present.

+  @retval  EFI_WRITE_PROTECTED    An attempt is being made to modify a

+                                  read-only attribute.

+  @retval  EFI_BAD_BUFFER_SIZE    The size of the buffer is lower than that indicated by

+                                  the data inside the buffer.

+  @retval  EFI_OUT_OF_RESOURCES   An allocation needed to process the request failed.

+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

+

+**/

+EFI_STATUS

+FileSetInfo (

+  IN EFI_FILE  *This,

+  IN EFI_GUID  *InformationType,

+  IN UINTN     BufferSize,

+  IN VOID      *Buffer

+  )

+{

+  SEMIHOST_FCB          *Fcb;

+  EFI_FILE_INFO         *Info;

+  EFI_FILE_SYSTEM_INFO  *SystemInfo;

+  CHAR16                *VolumeLabel;

+

+  if ((This == NULL) || (InformationType == NULL) || (Buffer == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Fcb = SEMIHOST_FCB_FROM_THIS (This);

+

+  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {

+    Info = Buffer;

+    if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {

+      return EFI_INVALID_PARAMETER;

+    }

+    if (BufferSize < Info->Size) {

+      return EFI_BAD_BUFFER_SIZE;

+    }

+    return SetFileInfo (Fcb, Info);

+  } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {

+    SystemInfo = Buffer;

+    if (SystemInfo->Size <

+        (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {

+      return EFI_INVALID_PARAMETER;

+    }

+    if (BufferSize < SystemInfo->Size) {

+      return EFI_BAD_BUFFER_SIZE;

+    }

+    Buffer = SystemInfo->VolumeLabel;

+

+    if (StrSize (Buffer) > 0) {

+      VolumeLabel = AllocateCopyPool (StrSize (Buffer), Buffer);

+      if (VolumeLabel != NULL) {

+        FreePool (mSemihostFsLabel);

+        mSemihostFsLabel = VolumeLabel;

+        return EFI_SUCCESS;

+      } else {

+        return EFI_OUT_OF_RESOURCES;

+      }

+    } else {

+      return EFI_INVALID_PARAMETER;

+    }

+  } else if (!CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {

+    return EFI_UNSUPPORTED;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+}

+

+EFI_STATUS

+FileFlush (

+  IN EFI_FILE *File

+  )

+{

+  SEMIHOST_FCB *Fcb;

+

+  Fcb = SEMIHOST_FCB_FROM_THIS(File);

+

+  if (Fcb->IsRoot) {

+    return EFI_SUCCESS;

+  } else {

+    if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)

+        || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {

+      return EFI_ACCESS_DENIED;

+    } else {

+      return EFI_SUCCESS;

+    }

+  }

+}

+

+EFI_STATUS

+SemihostFsEntryPoint (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_STATUS    Status;

+

+  Status = EFI_NOT_FOUND;

+

+  if (SemihostConnectionSupported ()) {

+    mSemihostFsLabel = AllocateCopyPool (StrSize (DEFAULT_SEMIHOST_FS_LABEL), DEFAULT_SEMIHOST_FS_LABEL);

+    if (mSemihostFsLabel == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &gInstallHandle,

+                    &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,

+                    &gEfiDevicePathProtocolGuid,       &gDevicePath,

+                    NULL

+                    );

+

+    if (EFI_ERROR(Status)) {

+      FreePool (mSemihostFsLabel);

+    }

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h
new file mode 100644
index 0000000..9339574
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h
@@ -0,0 +1,252 @@
+/** @file

+  Support a Semi Host file system over a debuggers JTAG

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __SEMIHOST_FS_H__

+#define __SEMIHOST_FS_H__

+

+EFI_STATUS

+VolumeOpen (

+  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,

+  OUT EFI_FILE                        **Root

+  );

+

+/**

+  Open a file on the host system by means of the semihosting interface.

+

+  @param[in]   This        A pointer to the EFI_FILE_PROTOCOL instance that is

+                           the file handle to source location.

+  @param[out]  NewHandle   A pointer to the location to return the opened

+                           handle for the new file.

+  @param[in]   FileName    The Null-terminated string of the name of the file

+                           to be opened.

+  @param[in]   OpenMode    The mode to open the file : Read or Read/Write or

+                           Read/Write/Create

+  @param[in]   Attributes  Only valid for EFI_FILE_MODE_CREATE, in which case these

+                           are the attribute bits for the newly created file. The

+                           mnemonics of the attribute bits are : EFI_FILE_READ_ONLY,

+                           EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED,

+                           EFI_FILE_DIRECTORY and EFI_FILE_ARCHIVE.

+

+  @retval  EFI_SUCCESS            The file was open.

+  @retval  EFI_NOT_FOUND          The specified file could not be found.

+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.

+  @retval  EFI_WRITE_PROTECTED    Attempt to create a directory. This is not possible

+                                  with the semi-hosting interface.

+  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to open the file.

+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

+

+**/

+EFI_STATUS

+FileOpen (

+  IN  EFI_FILE  *This,

+  OUT EFI_FILE  **NewHandle,

+  IN  CHAR16    *FileName,

+  IN  UINT64    OpenMode,

+  IN  UINT64    Attributes

+  );

+

+/**

+  Close a specified file handle.

+

+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file

+                    handle to close.

+

+  @retval  EFI_SUCCESS            The file was closed.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" is NULL.

+

+**/

+EFI_STATUS

+FileClose (

+  IN EFI_FILE  *This

+  );

+

+/**

+  Close and delete a file.

+

+  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file

+                    handle to delete.

+

+  @retval  EFI_SUCCESS              The file was closed and deleted.

+  @retval  EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.

+  @retval  EFI_INVALID_PARAMETER    The parameter "This" is NULL.

+

+**/

+EFI_STATUS

+FileDelete (

+  IN EFI_FILE *This

+  );

+

+/**

+  Read data from an open file.

+

+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that

+                              is the file handle to read data from.

+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the

+                              amount of data returned in Buffer. In both cases,

+                              the size is measured in bytes.

+  @param[out]     Buffer      The buffer into which the data is read.

+

+  @retval  EFI_SUCCESS            The data was read.

+  @retval  EFI_DEVICE_ERROR       On entry, the current file position is

+                                  beyond the end of the file, or the semi-hosting

+                                  interface reported an error while performing the

+                                  read operation.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" or the parameter "Buffer"

+                                  is NULL.

+**/

+EFI_STATUS

+FileRead (

+  IN     EFI_FILE  *This,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  );

+

+/**

+  Write data to an open file.

+

+  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that

+                              is the file handle to write data to.

+  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the

+                              size of the data actually written. In both cases,

+                              the size is measured in bytes.

+  @param[in]      Buffer      The buffer of data to write.

+

+  @retval  EFI_SUCCESS            The data was written.

+  @retval  EFI_ACCESS_DENIED      Attempt to write into a read only file or

+                                  in a file opened in read only mode.

+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" or the parameter "Buffer"

+                                  is NULL.

+

+**/

+EFI_STATUS

+FileWrite (

+  IN     EFI_FILE *This,

+  IN OUT UINTN    *BufferSize,

+  IN     VOID     *Buffer

+  );

+

+/**

+  Return a file's current position.

+

+  @param[in]   This      A pointer to the EFI_FILE_PROTOCOL instance that is

+                         the file handle to get the current position on.

+  @param[out]  Position  The address to return the file's current position value.

+

+  @retval  EFI_SUCCESS            The position was returned.

+  @retval  EFI_INVALID_PARAMETER  Position is a NULL pointer.

+

+**/

+EFI_STATUS

+FileGetPosition (

+  IN  EFI_FILE    *File,

+  OUT UINT64      *Position

+  );

+

+/**

+  Set a file's current position.

+

+  @param[in]  This      A pointer to the EFI_FILE_PROTOCOL instance that is

+                        the file handle to set the requested position on.

+  @param[in]  Position  The byte position from the start of the file to set.

+

+  @retval  EFI_SUCCESS       The position was set.

+  @retval  EFI_DEVICE_ERROR  The semi-hosting positionning operation failed.

+  @retval  EFI_UNSUPPORTED   The seek request for nonzero is not valid on open

+                             directories.

+

+**/

+EFI_STATUS

+FileSetPosition (

+  IN EFI_FILE *File,

+  IN UINT64   Position

+  );

+

+/**

+  Return information about a file or a file system.

+

+  @param[in]      This             A pointer to the EFI_FILE_PROTOCOL instance that

+                                   is the file handle the requested information is for.

+  @param[in]      InformationType  The type identifier for the information being requested :

+                                   EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or

+                                   EFI_FILE_SYSTEM_VOLUME_LABEL_ID

+  @param[in out]  BufferSize       The size, in bytes, of Buffer.

+  @param[out]     Buffer           A pointer to the data buffer to return. The type of the

+                                   data inside the buffer is indicated by InformationType.

+

+  @retval  EFI_SUCCESS           The information was returned.

+  @retval  EFI_UNSUPPORTED       The InformationType is not known.

+  @retval  EFI_BUFFER_TOO_SMALL  The BufferSize is too small to return the information.

+                                 BufferSize has been updated with the size needed to

+                                 complete the request.

+  @retval  EFI_INVALID_PARAMETER  The parameter "This" or the parameter "Buffer"

+                                  is NULL.

+

+**/

+EFI_STATUS

+FileGetInfo (

+  IN     EFI_FILE  *This,

+  IN     EFI_GUID  *InformationType,

+  IN OUT UINTN     *BufferSize,

+  OUT    VOID      *Buffer

+  );

+

+/**

+  Set information about a file or a file system.

+

+  @param[in]  This             A pointer to the EFI_FILE_PROTOCOL instance that

+                               is the file handle the information is for.

+  @param[in]  InformationType  The type identifier for the information being set :

+                               EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or

+                               EFI_FILE_SYSTEM_VOLUME_LABEL_ID

+  @param[in]  BufferSize       The size, in bytes, of Buffer.

+  @param[in]  Buffer           A pointer to the data buffer to write. The type of the

+                               data inside the buffer is indicated by InformationType.

+

+  @retval  EFI_SUCCESS            The information was set.

+  @retval  EFI_UNSUPPORTED        The InformationType is not known.

+  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.

+  @retval  EFI_ACCESS_DENIED      An attempt is being made to change the

+                                  EFI_FILE_DIRECTORY Attribute.

+  @retval  EFI_ACCESS_DENIED      InformationType is EFI_FILE_INFO_ID and

+                                  the file is a read-only file or has been

+                                  opened in read-only mode and an attempt is

+                                  being made to modify a field other than

+                                  Attribute.

+  @retval  EFI_ACCESS_DENIED      An attempt is made to change the name of a file

+                                  to a file that is already present.

+  @retval  EFI_WRITE_PROTECTED    An attempt is being made to modify a

+                                  read-only attribute.

+  @retval  EFI_BAD_BUFFER_SIZE    The size of the buffer is lower than that indicated by

+                                  the data inside the buffer.

+  @retval  EFI_OUT_OF_RESOURCES   An allocation needed to process the request failed.

+  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

+

+**/

+EFI_STATUS

+FileSetInfo (

+  IN EFI_FILE  *This,

+  IN EFI_GUID  *InformationType,

+  IN UINTN     BufferSize,

+  IN VOID      *Buffer

+  );

+

+EFI_STATUS

+FileFlush (

+  IN EFI_FILE *File

+  );

+

+#endif // __SEMIHOST_FS_H__

+

diff --git a/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
new file mode 100644
index 0000000..164df2d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
@@ -0,0 +1,48 @@
+#/** @file

+#  Support a Semi Host file system over a debuggers JTAG

+#

+#  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>

+#  Portions copyright (c) 2011 - 2013, 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.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SemihostFs

+  FILE_GUID                      = C5B9C74A-6D72-4719-99AB-C59F199091EB

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = SemihostFsEntryPoint

+

+[Sources.ARM, Sources.AARCH64]

+  Arm/SemihostFs.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  MemoryAllocationLib

+  SemihostLib

+  UefiDriverEntryPoint

+  UefiLib

+

+[Guids]

+  gEfiFileSystemInfoGuid

+  gEfiFileInfoGuid

+  gEfiFileSystemVolumeLabelInfoIdGuid

+

+[Protocols]

+  gEfiSimpleFileSystemProtocolGuid

+  gEfiDevicePathProtocolGuid

+

diff --git a/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.h b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.h
new file mode 100644
index 0000000..6904bdc
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.h
@@ -0,0 +1,303 @@
+/** @file

+  Macros to work around lack of Apple support for LDR register, =expr

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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 __MACRO_IO_LIB_H__

+#define __MACRO_IO_LIB_H__

+

+#if defined(__APPLE__)

+

+//

+//  ldr reg, =expr does not work with current Apple tool chain. So do the work our selves

+//

+

+// returns _Data in R0 and _Address in R1

+#define MmioWrite32(_Address, _Data) \

+  ldr  r1, [pc, #8]     ;            \

+  ldr  r0, [pc, #8]     ;            \

+  str  r0, [r1]         ;            \

+  b    1f               ;            \

+  .long (_Address)      ;            \

+  .long (_Data) ;                    \

+1:

+

+// returns _Data in R0 and _Address in R1, and _OrData in r2

+#define MmioOr32(_Address, _OrData) \

+  ldr  r1, [pc, #16]    ;           \

+  ldr  r2, [pc, #16]    ;           \

+  ldr  r0, [r1]         ;           \

+  orr  r0, r0, r2       ;           \

+  str  r0, [r1]         ;           \

+  b    1f               ;           \

+  .long (_Address)      ;           \

+  .long (_OrData)       ;           \

+1:

+

+// returns _Data in R0 and _Address in R1, and _OrData in r2

+#define MmioAnd32(_Address, _AndData) \

+  ldr  r1, [pc, #16]    ;             \

+  ldr  r2, [pc, #16]    ;             \

+  ldr  r0, [r1]         ;             \

+  and  r0, r0, r2       ;             \

+  str  r0, [r1]         ;             \

+  b    1f               ;             \

+  .long (_Address)      ;             \

+  .long (_AndData)       ;             \

+1:

+

+// returns result in R0, _Address in R1, and _OrData in r2

+#define MmioAndThenOr32(_Address, _AndData, _OrData)  \

+  ldr  r1, [pc, #24]    ;                             \

+  ldr  r0, [r1]         ;                             \

+  ldr  r2, [pc, #20]    ;                             \

+  and  r0, r0, r2       ;                             \

+  ldr  r2, [pc, #16]    ;                             \

+  orr  r0, r0, r2       ;                             \

+  str  r0, [r1]         ;                             \

+  b    1f               ;                             \

+  .long (_Address)      ;                             \

+  .long (_AndData)      ;                             \

+  .long (_OrData)       ;                             \

+1:

+

+// returns _Data in _Reg and _Address in R1

+#define MmioWriteFromReg32(_Address, _Reg) \

+  ldr  r1, [pc, #4]     ;                  \

+  str  _Reg, [r1]       ;                  \

+  b    1f               ;                  \

+  .long (_Address)      ;                  \

+1:

+

+

+// returns _Data in R0 and _Address in R1

+#define MmioRead32(_Address)   \

+  ldr  r1, [pc, #4]     ;      \

+  ldr  r0, [r1]         ;      \

+  b    1f               ;      \

+  .long (_Address)      ;      \

+1:

+

+// returns _Data in Reg and _Address in R1

+#define MmioReadToReg32(_Address, _Reg) \

+  ldr  r1, [pc, #4]     ;               \

+  ldr  _Reg, [r1]       ;               \

+  b    1f               ;               \

+  .long (_Address)      ;               \

+1:

+

+

+// load R0 with _Data

+#define LoadConstant(_Data)  \

+  ldr  r0, [pc, #0]     ;    \

+  b    1f               ;    \

+  .long (_Data)         ;    \

+1:

+

+// load _Reg with _Data

+#define LoadConstantToReg(_Data, _Reg)  \

+  ldr  _Reg, [pc, #0]   ;               \

+  b    1f               ;               \

+  .long (_Data)         ;               \

+1:

+

+// load _Reg with _Data if eq

+#define LoadConstantToRegIfEq(_Data, _Reg)  \

+  ldreq  _Reg, [pc, #0]   ;                 \

+  b    1f                 ;                 \

+  .long (_Data)           ;                 \

+1:

+

+// Reserve a region at the top of the Primary Core stack

+// for Global variables for the XIP phase

+#define SetPrimaryStack(StackTop, GlobalSize, Tmp)  \

+  and     Tmp, GlobalSize, #7         ;             \

+  rsbne   Tmp, Tmp, #8                ;             \

+  add     GlobalSize, GlobalSize, Tmp ;             \

+  sub     sp, StackTop, GlobalSize    ;             \

+                                      ;             \

+  mov     Tmp, sp                     ;             \

+  mov     GlobalSize, #0x0            ;             \

+_SetPrimaryStackInitGlobals:          ;             \

+  cmp     Tmp, StackTop               ;             \

+  beq     _SetPrimaryStackEnd         ;             \

+  str     GlobalSize, [Tmp], #4       ;             \

+  b       _SetPrimaryStackInitGlobals ;             \

+_SetPrimaryStackEnd:

+

+// Initialize the Global Variable with '0'

+#define InitializePrimaryStack(GlobalSize, Tmp1)    \

+  and     Tmp1, GlobalSize, #7        ;             \

+  rsbne   Tmp1, Tmp1, #8              ;             \

+  add     GlobalSize, GlobalSize, Tmp1 ;            \

+                                      ;             \

+  mov     Tmp1, sp                    ;             \

+  sub     sp, GlobalSize              ;             \

+  mov     GlobalSize, #0x0            ;             \

+_InitializePrimaryStackLoop:          ;             \

+  cmp     Tmp1, sp                    ;             \

+  bls     _InitializePrimaryStackEnd  ;             \

+  str     GlobalSize, [Tmp1, #-4]!    ;             \

+  b       _InitializePrimaryStackLoop ;             \

+_InitializePrimaryStackEnd:

+

+#elif defined (__GNUC__)

+

+#define MmioWrite32(Address, Data) \

+  ldr  r1, =Address ;              \

+  ldr  r0, =Data    ;              \

+  str  r0, [r1]

+

+#define MmioOr32(Address, OrData) \

+  ldr  r1, =Address ;             \

+  ldr  r2, =OrData  ;             \

+  ldr  r0, [r1]     ;             \

+  orr  r0, r0, r2   ;             \

+  str  r0, [r1]

+

+#define MmioAnd32(Address, AndData) \

+  ldr  r1, =Address ;               \

+  ldr  r2, =AndData ;               \

+  ldr  r0, [r1]     ;               \

+  and  r0, r0, r2   ;               \

+  str  r0, [r1]

+

+#define MmioAndThenOr32(Address, AndData, OrData) \

+  ldr  r1, =Address ;                             \

+  ldr  r0, [r1]     ;                             \

+  ldr  r2, =AndData ;                             \

+  and  r0, r0, r2   ;                             \

+  ldr  r2, =OrData  ;                             \

+  orr  r0, r0, r2   ;                             \

+  str  r0, [r1]

+

+#define MmioWriteFromReg32(Address, Reg) \

+  ldr  r1, =Address ;                    \

+  str  Reg, [r1]

+

+#define MmioRead32(Address) \

+  ldr  r1, =Address ;       \

+  ldr  r0, [r1]

+

+#define MmioReadToReg32(Address, Reg) \

+  ldr  r1, =Address ;                 \

+  ldr  Reg, [r1]

+

+#define LoadConstant(Data) \

+  ldr  r0, =Data

+

+#define LoadConstantToReg(Data, Reg) \

+  ldr  Reg, =Data

+

+#define SetPrimaryStack(StackTop, GlobalSize, Tmp)  \

+  and     Tmp, GlobalSize, #7         ;             \

+  rsbne   Tmp, Tmp, #8                ;             \

+  add     GlobalSize, GlobalSize, Tmp ;             \

+  sub     sp, StackTop, GlobalSize    ;             \

+                                      ;             \

+  mov     Tmp, sp                     ;             \

+  mov     GlobalSize, #0x0            ;             \

+_SetPrimaryStackInitGlobals:          ;             \

+  cmp     Tmp, StackTop               ;             \

+  beq     _SetPrimaryStackEnd         ;             \

+  str     GlobalSize, [Tmp], #4       ;             \

+  b       _SetPrimaryStackInitGlobals ;             \

+_SetPrimaryStackEnd:

+

+// Initialize the Global Variable with '0'

+#define InitializePrimaryStack(GlobalSize, Tmp1)    \

+  and     Tmp1, GlobalSize, #7        ;             \

+  rsbne   Tmp1, Tmp1, #8              ;             \

+  add     GlobalSize, GlobalSize, Tmp1 ;            \

+                                      ;             \

+  mov     Tmp1, sp                    ;             \

+  sub     sp, GlobalSize              ;             \

+  mov     GlobalSize, #0x0            ;             \

+_InitializePrimaryStackLoop:          ;             \

+  cmp     Tmp1, sp                    ;             \

+  bls     _InitializePrimaryStackEnd  ;             \

+  str     GlobalSize, [Tmp1, #-4]!    ;             \

+  b       _InitializePrimaryStackLoop ;             \

+_InitializePrimaryStackEnd:

+

+#else

+

+//

+// Use ARM assembly macros, form armasam

+//

+//  Less magic in the macros if ldr reg, =expr works

+//

+

+// returns _Data in R0 and _Address in R1

+

+

+

+#define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data

+

+

+

+

+// returns Data in R0 and Address in R1, and OrData in r2

+#define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData

+

+

+// returns _Data in R0 and _Address in R1, and _OrData in r2

+

+

+#define MmioAnd32(Address, AndData)  MmioAnd32Macro Address, AndData

+

+// returns result in R0, _Address in R1, and _OrData in r2

+

+

+#define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData

+

+

+// returns _Data in _Reg and _Address in R1

+

+

+#define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg

+

+// returns _Data in R0 and _Address in R1

+

+

+#define MmioRead32(Address)  MmioRead32Macro Address

+

+// returns _Data in Reg and _Address in R1

+

+

+#define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg

+

+

+// load R0 with _Data

+

+

+#define LoadConstant(Data)  LoadConstantMacro Data

+

+// load _Reg with _Data

+

+

+#define LoadConstantToReg(Data, Reg)  LoadConstantToRegMacro Data, Reg

+

+// conditional load testing eq flag

+#define LoadConstantToRegIfEq(Data, Reg)  LoadConstantToRegIfEqMacro Data, Reg

+

+#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp

+

+// Initialize the Global Variable with '0'

+#define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1

+

+#endif

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.inc b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.inc
new file mode 100644
index 0000000..301bd89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.inc
@@ -0,0 +1,121 @@
+;%HEADER%

+;/** @file

+;  Macros to work around lack of Apple support for LDR register, =expr

+;

+;  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>

+;  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.

+;

+;**/

+

+

+  MACRO

+  MmioWrite32Macro $Address, $Data

+  ldr  r1, = ($Address)

+  ldr  r0, = ($Data)

+  str  r0, [r1]

+  MEND

+

+  MACRO

+  MmioOr32Macro $Address, $OrData

+  ldr  r1, =($Address)

+  ldr  r2, =($OrData)

+  ldr  r0, [r1]

+  orr  r0, r0, r2

+  str  r0, [r1]

+  MEND

+

+  MACRO

+  MmioAnd32Macro $Address, $AndData

+  ldr  r1, =($Address)

+  ldr  r2, =($AndData)

+  ldr  r0, [r1]

+  and  r0, r0, r2

+  str  r0, [r1]

+  MEND

+

+  MACRO

+  MmioAndThenOr32Macro $Address, $AndData, $OrData

+  ldr  r1, =($Address)

+  ldr  r0, [r1]

+  ldr  r2, =($AndData)

+  and  r0, r0, r2

+  ldr  r2, =($OrData)

+  orr  r0, r0, r2

+  str  r0, [r1]

+  MEND

+

+  MACRO

+  MmioWriteFromReg32Macro $Address, $Reg

+  ldr  r1, =($Address)

+  str  $Reg, [r1]

+  MEND

+

+  MACRO

+  MmioRead32Macro $Address

+  ldr  r1, =($Address)

+  ldr  r0, [r1]

+  MEND

+

+  MACRO

+  MmioReadToReg32Macro $Address, $Reg

+  ldr  r1, =($Address)

+  ldr  $Reg, [r1]

+  MEND

+

+  MACRO

+  LoadConstantMacro $Data

+  ldr  r0, =($Data)

+  MEND

+

+  MACRO

+  LoadConstantToRegMacro $Data, $Reg

+  ldr  $Reg, =($Data)

+  MEND

+

+  ; The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack

+  ; Note: Global Size will be modified

+  MACRO

+  SetPrimaryStack $StackTop, $GlobalSize, $Tmp

+  and     $Tmp, $GlobalSize, #7

+  rsbne   $Tmp, $Tmp, #8

+  add     $GlobalSize, $GlobalSize, $Tmp

+  sub     sp, $StackTop, $GlobalSize

+

+  ; Set all the global variables to 0

+  mov     $Tmp, sp

+  mov     $GlobalSize, #0x0

+_SetPrimaryStackInitGlobals

+  cmp     $Tmp, $StackTop

+  beq     _SetPrimaryStackEnd

+  str     $GlobalSize, [$Tmp], #4

+  b       _SetPrimaryStackInitGlobals

+_SetPrimaryStackEnd

+  MEND

+

+  MACRO

+  InitializePrimaryStack $GlobalSize, $Tmp1

+  and     $Tmp1, $GlobalSize, #7

+  rsbne   $Tmp1, $Tmp1, #8

+  add     $GlobalSize, $GlobalSize, $Tmp1

+

+  mov     $Tmp1, sp

+  sub     sp, $GlobalSize

+  ; Set all the global variables to 0

+  mov     $GlobalSize, #0x0

+_InitializePrimaryStackLoop

+  cmp     $Tmp1, sp

+  bls     _InitializePrimaryStackEnd

+  str     $GlobalSize, [$Tmp1, #-4]!

+  b       _InitializePrimaryStackLoop

+_InitializePrimaryStackEnd

+  MEND

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLibV8.h b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLibV8.h
new file mode 100644
index 0000000..2ee1081
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLibV8.h
@@ -0,0 +1,110 @@
+/** @file

+  Macros to work around lack of Clang support for LDR register, =expr

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Portions 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.

+

+**/

+

+

+#ifndef __MACRO_IO_LIBV8_H__

+#define __MACRO_IO_LIBV8_H__

+

+#define SetPrimaryStack(StackTop, GlobalSize, Tmp, Tmp1)  \

+  ands    Tmp, GlobalSize, #15        ;                   \

+  mov     Tmp1, #16                   ;                   \

+  sub     Tmp1, Tmp1, Tmp             ;                   \

+  csel    Tmp, Tmp1, Tmp, ne          ;                   \

+  add     GlobalSize, GlobalSize, Tmp ;                   \

+  sub     sp, StackTop, GlobalSize    ;                   \

+                                      ;                   \

+  mov     Tmp, sp                     ;                   \

+  mov     GlobalSize, #0x0            ;                   \

+_SetPrimaryStackInitGlobals:          ;                   \

+  cmp     Tmp, StackTop               ;                   \

+  b.eq    _SetPrimaryStackEnd         ;                   \

+  str     GlobalSize, [Tmp], #8       ;                   \

+  b       _SetPrimaryStackInitGlobals ;                   \

+_SetPrimaryStackEnd:

+

+// Initialize the Global Variable with '0'

+#define InitializePrimaryStack(GlobalSize, Tmp1, Tmp2) \

+  and     Tmp1, GlobalSize, #15       ;             \

+  mov     Tmp2, #16                   ;             \

+  sub     Tmp2, Tmp2, Tmp1            ;             \

+  add     GlobalSize, GlobalSize, Tmp2 ;            \

+                                      ;             \

+  mov     Tmp1, sp                    ;             \

+  sub     sp, sp, GlobalSize          ;             \

+  mov     GlobalSize, #0x0            ;             \

+_InitializePrimaryStackLoop:          ;             \

+  mov     Tmp2, sp                    ;             \

+  cmp     Tmp1, Tmp2                  ;             \

+  bls     _InitializePrimaryStackEnd  ;             \

+  str     GlobalSize, [Tmp1, #-8]!    ;             \

+  b       _InitializePrimaryStackLoop ;             \

+_InitializePrimaryStackEnd:

+

+// CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1

+// This only selects between EL1 and EL2, else we die.

+// Provide the Macro with a safe temp xreg to use.

+#define EL1_OR_EL2(SAFE_XREG)        \

+        mrs    SAFE_XREG, CurrentEL ;\

+        cmp    SAFE_XREG, #0x8      ;\

+        b.eq   2f                   ;\

+        cmp    SAFE_XREG, #0x4      ;\

+        b.ne   .                    ;// We should never get here

+// EL1 code starts here

+

+// CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1

+// This only selects between EL1 and EL2 and EL3, else we die.

+// Provide the Macro with a safe temp xreg to use.

+#define EL1_OR_EL2_OR_EL3(SAFE_XREG) \

+        mrs    SAFE_XREG, CurrentEL ;\

+        cmp    SAFE_XREG, #0xC      ;\

+        b.eq   3f                   ;\

+        cmp    SAFE_XREG, #0x8      ;\

+        b.eq   2f                   ;\

+        cmp    SAFE_XREG, #0x4      ;\

+        b.ne   .                    ;// We should never get here

+// EL1 code starts here

+#if defined(__clang__)

+

+// load x0 with _Data

+#define LoadConstant(_Data)              \

+  ldr  x0, 1f                          ; \

+  b    2f                              ; \

+.align(8)                              ; \

+1:                                       \

+  .8byte (_Data)                       ; \

+2:

+

+// load _Reg with _Data

+#define LoadConstantToReg(_Data, _Reg)    \

+  ldr  _Reg, 1f                         ; \

+  b    2f                               ; \

+.align(8)                               ; \

+1:                                        \

+  .8byte (_Data)                        ; \

+2:

+

+#elif defined (__GNUC__)

+

+#define LoadConstant(Data) \

+  ldr  x0, =Data

+

+#define LoadConstantToReg(Data, Reg) \

+  ldr  Reg, =Data

+

+#endif // __GNUC__

+

+#endif // __MACRO_IO_LIBV8_H__

+

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64.h
new file mode 100644
index 0000000..0400740
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64.h
@@ -0,0 +1,189 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __AARCH64_H__

+#define __AARCH64_H__

+

+#include <Chipset/AArch64Mmu.h>

+#include <Chipset/ArmArchTimer.h>

+

+// ARM Interrupt ID in Exception Table

+#define ARM_ARCH_EXCEPTION_IRQ            EXCEPT_AARCH64_IRQ

+

+// CPACR - Coprocessor Access Control Register definitions

+#define CPACR_TTA_EN            (1UL << 28)

+#define CPACR_FPEN_EL1          (1UL << 20)

+#define CPACR_FPEN_FULL         (3UL << 20)

+#define CPACR_CP_FULL_ACCESS    0x300000

+

+// Coprocessor Trap Register (CPTR)

+#define AARCH64_CPTR_TFP        (1 << 10)

+

+// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions

+#define AARCH64_PFR0_FP         (0xF << 16)

+#define AARCH64_PFR0_GIC        (0xF << 24)

+

+// SCR - Secure Configuration Register definitions

+#define SCR_NS                  (1 << 0)

+#define SCR_IRQ                 (1 << 1)

+#define SCR_FIQ                 (1 << 2)

+#define SCR_EA                  (1 << 3)

+#define SCR_FW                  (1 << 4)

+#define SCR_AW                  (1 << 5)

+

+// MIDR - Main ID Register definitions

+#define ARM_CPU_TYPE_MASK       0xFFF

+#define ARM_CPU_TYPE_AEMv8      0xD0F

+#define ARM_CPU_TYPE_A53        0xD03

+#define ARM_CPU_TYPE_A57        0xD07

+#define ARM_CPU_TYPE_A15        0xC0F

+#define ARM_CPU_TYPE_A9         0xC09

+#define ARM_CPU_TYPE_A5         0xC05

+

+#define ARM_CPU_REV_MASK        ((0xF << 20) | (0xF) )

+#define ARM_CPU_REV(rn, pn)     ((((rn) & 0xF) << 20) | ((pn) & 0xF))

+

+// Hypervisor Configuration Register

+#define ARM_HCR_FMO       BIT3

+#define ARM_HCR_IMO       BIT4

+#define ARM_HCR_AMO       BIT5

+#define ARM_HCR_TSC       BIT19

+#define ARM_HCR_TGE       BIT27

+

+// Exception Syndrome Register

+#define AARCH64_ESR_EC(Ecr)    ((0x3F << 26) & (Ecr))

+#define AARCH64_ESR_ISS(Ecr)   ((0x1FFFFFF) & (Ecr))

+

+#define AARCH64_ESR_EC_SMC32   (0x13 << 26)

+#define AARCH64_ESR_EC_SMC64   (0x17 << 26)

+

+// AArch64 Exception Level

+#define AARCH64_EL3       0xC

+#define AARCH64_EL2       0x8

+#define AARCH64_EL1       0x4

+

+// Saved Program Status Register definitions

+#define SPSR_A                  BIT8

+#define SPSR_I                  BIT7

+#define SPSR_F                  BIT6

+

+#define SPSR_AARCH32            BIT4

+

+#define SPSR_AARCH32_MODE_USER  0x0

+#define SPSR_AARCH32_MODE_FIQ   0x1

+#define SPSR_AARCH32_MODE_IRQ   0x2

+#define SPSR_AARCH32_MODE_SVC   0x3

+#define SPSR_AARCH32_MODE_ABORT 0x7

+#define SPSR_AARCH32_MODE_UNDEF 0xB

+#define SPSR_AARCH32_MODE_SYS   0xF

+

+// Counter-timer Hypervisor Control register definitions

+#define CNTHCTL_EL2_EL1PCTEN    BIT0

+#define CNTHCTL_EL2_EL1PCEN     BIT1

+

+#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 11)-1)

+

+VOID

+EFIAPI

+ArmEnableSWPInstruction (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadCbar (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadTpidrurw (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteTpidrurw (

+  UINTN Value

+  );

+

+UINTN

+EFIAPI

+ArmGetTCR (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmSetTCR (

+  UINTN Value

+  );

+

+UINTN

+EFIAPI

+ArmGetMAIR (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmSetMAIR (

+  UINTN Value

+  );

+

+VOID

+EFIAPI

+ArmDisableAlignmentCheck (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableAlignmentCheck (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDisableAllExceptions (

+  VOID

+  );

+

+VOID

+ArmWriteHcr (

+  IN UINTN Hcr

+  );

+

+UINTN

+ArmReadCurrentEL (

+  VOID

+  );

+

+UINT64

+PageAttributeToGcdAttribute (

+  IN UINT64 PageAttributes

+  );

+

+UINT64

+GcdAttributeToPageAttribute (

+  IN UINT64 GcdAttributes

+  );

+

+UINTN

+ArmWriteCptr (

+  IN  UINT64 Cptr

+  );

+

+#endif // __AARCH64_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64Mmu.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64Mmu.h
new file mode 100644
index 0000000..77a96ec
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64Mmu.h
@@ -0,0 +1,211 @@
+/** @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.

+*

+**/

+

+#ifndef __AARCH64_MMU_H_

+#define __AARCH64_MMU_H_

+

+//

+// Memory Attribute Indirection register Definitions

+//

+#define MAIR_ATTR_DEVICE_MEMORY                 0x0ULL

+#define MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE   0x44ULL

+#define MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH   0xBBULL

+#define MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK      0xFFULL

+

+#define MAIR_ATTR(n,value)                      ((value) << (((n) >> 2)*8))

+

+//

+// Long-descriptor Translation Table format

+//

+

+// Return the smallest offset from the table level.

+// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0

+#define TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel)  (12 + ((3 - (TableLevel)) * 9))

+

+#define TT_BLOCK_ENTRY_SIZE_AT_LEVEL(Level)     (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(Level))

+

+// Get the associated entry in the given Translation Table

+#define TT_GET_ENTRY_FOR_ADDRESS(TranslationTable, Level, Address)  \

+    ((UINTN)(TranslationTable) + ((((UINTN)(Address) >> TT_ADDRESS_OFFSET_AT_LEVEL(Level)) & (BIT9-1)) * sizeof(UINT64)))

+

+// Return the smallest address granularity from the table level.

+// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0

+#define TT_ADDRESS_AT_LEVEL(TableLevel)       (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel))

+

+#define TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount) \

+    ((UINT64*)((EFI_PHYSICAL_ADDRESS)(TranslationTable) + (((EntryCount) - 1) * sizeof(UINT64))))

+

+// There are 512 entries per table when 4K Granularity

+#define TT_ENTRY_COUNT                          512

+#define TT_ALIGNMENT_BLOCK_ENTRY                BIT12

+#define TT_ALIGNMENT_DESCRIPTION_TABLE          BIT12

+

+#define TT_ADDRESS_MASK_BLOCK_ENTRY             (0xFFFFFFFULL << 12)

+#define TT_ADDRESS_MASK_DESCRIPTION_TABLE       (0xFFFFFFFULL << 12)

+

+#define TT_TYPE_MASK                            0x3

+#define TT_TYPE_TABLE_ENTRY                     0x3

+#define TT_TYPE_BLOCK_ENTRY                     0x1

+#define TT_TYPE_BLOCK_ENTRY_LEVEL3              0x3

+

+#define TT_ATTR_INDX_MASK                       (0x7 << 2)

+#define TT_ATTR_INDX_DEVICE_MEMORY              (0x0 << 2)

+#define TT_ATTR_INDX_MEMORY_NON_CACHEABLE       (0x1 << 2)

+#define TT_ATTR_INDX_MEMORY_WRITE_THROUGH       (0x2 << 2)

+#define TT_ATTR_INDX_MEMORY_WRITE_BACK          (0x3 << 2)

+

+#define TT_AP_MASK                              (0x3UL << 6)

+#define TT_AP_NO_RW                             (0x0UL << 6)

+#define TT_AP_RW_RW                             (0x1UL << 6)

+#define TT_AP_NO_RO                             (0x2UL << 6)

+#define TT_AP_RO_RO                             (0x3UL << 6)

+

+#define TT_NS                                   BIT5

+#define TT_AF                                   BIT10

+

+#define TT_PXN_MASK                             BIT53

+#define TT_UXN_MASK                             BIT54

+

+#define TT_ATTRIBUTES_MASK                      ((0xFFFULL << 52) | (0x3FFULL << 2))

+

+#define TT_TABLE_PXN                            BIT59

+#define TT_TABLE_XN                             BIT60

+#define TT_TABLE_NS                             BIT63

+

+#define TT_TABLE_AP_MASK                        (BIT62 | BIT61)

+#define TT_TABLE_AP_NO_PERMISSION               (0x0ULL << 61)

+#define TT_TABLE_AP_EL0_NO_ACCESS               (0x1ULL << 61)

+#define TT_TABLE_AP_NO_WRITE_ACCESS             (0x2ULL << 61)

+

+//

+// Translation Control Register

+//

+#define TCR_T0SZ_MASK                           0x3F

+

+#define TCR_PS_4GB                              (0 << 16)

+#define TCR_PS_64GB                             (1 << 16)

+#define TCR_PS_1TB                              (2 << 16)

+#define TCR_PS_4TB                              (3 << 16)

+#define TCR_PS_16TB                             (4 << 16)

+#define TCR_PS_256TB                            (5 << 16)

+

+#define TCR_TG0_4KB                             (0 << 14)

+

+#define TCR_IPS_4GB                             (0ULL << 32)

+#define TCR_IPS_64GB                            (1ULL << 32)

+#define TCR_IPS_1TB                             (2ULL << 32)

+#define TCR_IPS_4TB                             (3ULL << 32)

+#define TCR_IPS_16TB                            (4ULL << 32)

+#define TCR_IPS_256TB                           (5ULL << 32)

+

+

+#define TTBR_ASID_FIELD                      (48)

+#define TTBR_ASID_MASK                       (0xFF << TTBR_ASID_FIELD)

+#define TTBR_BADDR_MASK                      (0xFFFFFFFFFFFF ) // The width of this field depends on the values in TxSZ. Addr occupies bottom 48bits

+

+#define TCR_EL1_T0SZ_FIELD                   (0)

+#define TCR_EL1_EPD0_FIELD                   (7)

+#define TCR_EL1_IRGN0_FIELD                  (8)

+#define TCR_EL1_ORGN0_FIELD                  (10)

+#define TCR_EL1_SH0_FIELD                    (12)

+#define TCR_EL1_TG0_FIELD                    (14)

+#define TCR_EL1_T1SZ_FIELD                   (16)

+#define TCR_EL1_A1_FIELD                     (22)

+#define TCR_EL1_EPD1_FIELD                   (23)

+#define TCR_EL1_IRGN1_FIELD                  (24)

+#define TCR_EL1_ORGN1_FIELD                  (26)

+#define TCR_EL1_SH1_FIELD                    (28)

+#define TCR_EL1_TG1_FIELD                    (30)

+#define TCR_EL1_IPS_FIELD                    (32)

+#define TCR_EL1_AS_FIELD                     (36)

+#define TCR_EL1_TBI0_FIELD                   (37)

+#define TCR_EL1_TBI1_FIELD                   (38)

+#define TCR_EL1_T0SZ_MASK                    (0x1F << TCR_EL1_T0SZ_FIELD)

+#define TCR_EL1_EPD0_MASK                    (0x1  << TCR_EL1_EPD0_FIELD)

+#define TCR_EL1_IRGN0_MASK                   (0x3  << TCR_EL1_IRGN0_FIELD)

+#define TCR_EL1_ORGN0_MASK                   (0x3  << TCR_EL1_ORGN0_FIELD)

+#define TCR_EL1_SH0_MASK                     (0x3  << TCR_EL1_SH0_FIELD)

+#define TCR_EL1_TG0_MASK                     (0x1  << TCR_EL1_TG0_FIELD)

+#define TCR_EL1_T1SZ_MASK                    (0x1F << TCR_EL1_T1SZ_FIELD)

+#define TCR_EL1_A1_MASK                      (0x1  << TCR_EL1_A1_FIELD)

+#define TCR_EL1_EPD1_MASK                    (0x1  << TCR_EL1_EPD1_FIELD)

+#define TCR_EL1_IRGN1_MASK                   (0x3  << TCR_EL1_IRGN1_FIELD)

+#define TCR_EL1_ORGN1_MASK                   (0x3  << TCR_EL1_ORGN1_FIELD)

+#define TCR_EL1_SH1_MASK                     (0x3  << TCR_EL1_SH1_FIELD)

+#define TCR_EL1_TG1_MASK                     (0x1  << TCR_EL1_TG1_FIELD)

+#define TCR_EL1_IPS_MASK                     (0x7  << TCR_EL1_IPS_FIELD)

+#define TCR_EL1_AS_MASK                      (0x1  << TCR_EL1_AS_FIELD)

+#define TCR_EL1_TBI0_MASK                    (0x1  << TCR_EL1_TBI0_FIELD)

+#define TCR_EL1_TBI1_MASK                    (0x1  << TCR_EL1_TBI1_FIELD)

+

+

+#define VTCR_EL23_T0SZ_FIELD                 (0)

+#define VTCR_EL23_IRGN0_FIELD                (8)

+#define VTCR_EL23_ORGN0_FIELD                (10)

+#define VTCR_EL23_SH0_FIELD                  (12)

+#define TCR_EL23_TG0_FIELD                   (14)

+#define VTCR_EL23_PS_FIELD                   (16)

+#define TCR_EL23_T0SZ_MASK                   (0x1F << VTCR_EL23_T0SZ_FIELD)

+#define TCR_EL23_IRGN0_MASK                  (0x3  << VTCR_EL23_IRGN0_FIELD)

+#define TCR_EL23_ORGN0_MASK                  (0x3  << VTCR_EL23_ORGN0_FIELD)

+#define TCR_EL23_SH0_MASK                    (0x3  << VTCR_EL23_SH0_FIELD)

+#define TCR_EL23_TG0_MASK                    (0x1  << TCR_EL23_TG0_FIELD)

+#define TCR_EL23_PS_MASK                     (0x7  << VTCR_EL23_PS_FIELD)

+

+

+#define VTCR_EL2_T0SZ_FIELD                  (0)

+#define VTCR_EL2_SL0_FIELD                   (6)

+#define VTCR_EL2_IRGN0_FIELD                 (8)

+#define VTCR_EL2_ORGN0_FIELD                 (10)

+#define VTCR_EL2_SH0_FIELD                   (12)

+#define VTCR_EL2_TG0_FIELD                   (14)

+#define VTCR_EL2_PS_FIELD                    (16)

+#define VTCR_EL2_T0SZ_MASK                   (0x1F << VTCR_EL2_T0SZ_FIELD)

+#define VTCR_EL2_SL0_MASK                    (0x1F << VTCR_EL2_SL0_FIELD)

+#define VTCR_EL2_IRGN0_MASK                  (0x3  << VTCR_EL2_IRGN0_FIELD)

+#define VTCR_EL2_ORGN0_MASK                  (0x3  << VTCR_EL2_ORGN0_FIELD)

+#define VTCR_EL2_SH0_MASK                    (0x3  << VTCR_EL2_SH0_FIELD)

+#define VTCR_EL2_TG0_MASK                    (0x1  << VTCR_EL2_TG0_FIELD)

+#define VTCR_EL2_PS_MASK                     (0x7  << VTCR_EL2_PS_FIELD)

+

+

+#define TCR_RGN_OUTER_NON_CACHEABLE          (0x0 << 10)

+#define TCR_RGN_OUTER_WRITE_BACK_ALLOC       (0x1 << 10)

+#define TCR_RGN_OUTER_WRITE_THROUGH          (0x2 << 10)

+#define TCR_RGN_OUTER_WRITE_BACK_NO_ALLOC    (0x3 << 10)

+

+#define TCR_RGN_INNER_NON_CACHEABLE          (0x0 << 8)

+#define TCR_RGN_INNER_WRITE_BACK_ALLOC       (0x1 << 8)

+#define TCR_RGN_INNER_WRITE_THROUGH          (0x2 << 8)

+#define TCR_RGN_INNER_WRITE_BACK_NO_ALLOC    (0x3 << 8)

+

+#define TCR_SH_NON_SHAREABLE                 (0x0 << 12)

+#define TCR_SH_OUTER_SHAREABLE               (0x2 << 12)

+#define TCR_SH_INNER_SHAREABLE               (0x3 << 12)

+

+#define TCR_PASZ_32BITS_4GB                  (0x0)

+#define TCR_PASZ_36BITS_64GB                 (0x1)

+#define TCR_PASZ_40BITS_1TB                  (0x2)

+#define TCR_PASZ_42BITS_4TB                  (0x3)

+#define TCR_PASZ_44BITS_16TB                 (0x4)

+#define TCR_PASZ_48BITS_256TB                (0x5)

+

+// The value written to the T*SZ fields are defined as 2^(64-T*SZ). So a 39Bit

+// Virtual address range for 512GB of virtual space sets T*SZ to 25

+#define INPUT_ADDRESS_SIZE_TO_TxSZ(a)        (64 - a)

+

+// Uses LPAE Page Table format

+

+#endif // __AARCH64_MMU_H_

+

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM1176JZ-S.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM1176JZ-S.h
new file mode 100644
index 0000000..ba24bcb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM1176JZ-S.h
@@ -0,0 +1,127 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __ARM1176JZ_S_H__

+#define __ARM1176JZ_S_H__

+

+// Domain Access Control Register

+#define DOMAIN_ACCESS_CONTROL_MASK(a)     (3UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_NONE(a)     (0UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_CLIENT(a)   (1UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_MANAGER(a)  (3UL << (2 * (a)))

+

+#define TRANSLATION_TABLE_SIZE            (16 * 1024)

+#define TRANSLATION_TABLE_ALIGNMENT       (16 * 1024)

+#define TRANSLATION_TABLE_ALIGNMENT_MASK  (TRANSLATION_TABLE_ALIGNMENT - 1)

+

+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))

+

+// Translation table descriptor types

+#define TT_DESCRIPTOR_TYPE_MASK         ((1UL << 18) | (3UL << 0))

+#define TT_DESCRIPTOR_TYPE_PAGE_TABLE   ((0UL << 18) | (1UL << 0))

+#define TT_DESCRIPTOR_TYPE_SECTION      ((0UL << 18) | (2UL << 0))

+#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))

+

+// Section descriptor definitions

+#define TT_DESCRIPTOR_SECTION_SIZE                              (0x00100000)

+

+#define TT_DESCRIPTOR_SECTION_NS_MASK                           (1UL << 19)

+#define TT_DESCRIPTOR_SECTION_NS                                (1UL << 19)

+

+#define TT_DESCRIPTOR_SECTION_NG_MASK                           (1UL << 17)

+#define TT_DESCRIPTOR_SECTION_NG_GLOBAL                         (0UL << 17)

+#define TT_DESCRIPTOR_SECTION_NG_LOCAL                          (1UL << 17)

+

+#define TT_DESCRIPTOR_SECTION_S_MASK                            (1UL << 16)

+#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      (0UL << 16)

+#define TT_DESCRIPTOR_SECTION_S_SHARED                          (1UL << 16)

+

+#define TT_DESCRIPTOR_SECTION_AP_MASK                           ((1UL << 15) | (3UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_NO_NO                          ((0UL << 15) | (0UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RW_NO                          ((0UL << 15) | (1UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RW_RO                          ((0UL << 15) | (2UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RW_RW                          ((0UL << 15) | (3UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RO_NO                          ((1UL << 15) | (1UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RO_RO                          ((1UL << 15) | (3UL << 10))

+

+#define TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE                (0UL)

+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE          (1UL)

+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE    (2UL)

+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE       (3UL)

+

+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_MASK                       ((1UL << 14) | (3UL << 12))

+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_NON_CACHEABLE              ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE             << 12))

+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_ALLOCATE        ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE       << 12))

+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE  ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE << 12))

+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE     ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE    << 12))

+

+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_MASK                       (3UL << 2)

+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_NON_CACHEABLE              (TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE             << 2)

+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_ALLOCATE        (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE       << 2)

+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE  (TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE << 2)

+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE     (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE    << 2)

+

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK                   (TT_DESCRIPTOR_OUTER_CACHE_POLICY_MASK                      | TT_DESCRIPTOR_INNER_CACHE_POLICY_MASK)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC    (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE    | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE          (TT_DESCRIPTOR_OUTER_CACHE_POLICY_NON_CACHEABLE             | TT_DESCRIPTOR_INNER_CACHE_POLICY_NON_CACHEABLE)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC       (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_ALLOCATE       | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_ALLOCATE)

+

+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK                       (0x0FUL << 5)

+#define TT_DESCRIPTOR_SECTION_DOMAIN(a)                         (((a) & 0x0FUL) << 5)

+

+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK                 (0xFFF00000)

+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a)                   (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)

+

+#define TT_DESCRIPTOR_SECTION_WRITE_BACK(NonSecure)             (TT_DESCRIPTOR_TYPE_SECTION                                                          | \

+                                                                (NonSecure ? TT_DESCRIPTOR_SECTION_NS : 0)   | \

+                                                                TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                                TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                                TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                                TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                                TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)

+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(NonSecure)          (TT_DESCRIPTOR_TYPE_SECTION                                                          | \

+                                                                (NonSecure ? TT_DESCRIPTOR_SECTION_NS : 0)   | \

+                                                                TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                                TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                                TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                                TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                                TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)

+#define TT_DESCRIPTOR_SECTION_UNCACHED(NonSecure)               (TT_DESCRIPTOR_TYPE_SECTION                                                          | \

+                                                                (NonSecure ? TT_DESCRIPTOR_SECTION_NS : 0)   | \

+                                                                TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                                TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                                TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                                TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                                TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)

+

+#define CPACR_CP_FULL_ACCESS    0x0FFFFFFF

+

+// NSACR - Non-Secure Access Control Register definitions

+#define NSACR_CP(cp)            ((1 << (cp)) & 0x3FFF)

+#define NSACR_PLE               0

+#define NSACR_TL                0

+#define NSACR_NS_SMP            0

+

+// SCR - Secure Configuration Register definitions

+#define SCR_NS                  (1 << 0)

+#define SCR_IRQ                 (1 << 1)

+#define SCR_FIQ                 (1 << 2)

+#define SCR_EA                  (1 << 3)

+#define SCR_FW                  (1 << 4)

+#define SCR_AW                  (1 << 5)

+

+#endif // __ARM1176JZ_S_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM926EJ-S.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM926EJ-S.h
new file mode 100644
index 0000000..4ef1103
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM926EJ-S.h
@@ -0,0 +1,71 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __ARM926EJ_S_H__

+#define __ARM926EJ_S_H__

+

+// Domain Access Control Register

+#define DOMAIN_ACCESS_CONTROL_MASK(a)     (3UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_NONE(a)     (0UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_CLIENT(a)   (1UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_MANAGER(a)  (3UL << (2 * (a)))

+

+#define TRANSLATION_TABLE_SIZE            (16 * 1024)

+#define TRANSLATION_TABLE_ALIGNMENT       (16 * 1024)

+#define TRANSLATION_TABLE_ALIGNMENT_MASK  (TRANSLATION_TABLE_ALIGNMENT - 1)

+

+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))

+

+// Translation table descriptor types

+#define TT_DESCRIPTOR_TYPE_MASK     (3UL << 0)

+#define TT_DESCRIPTOR_TYPE_FAULT    (0UL << 0)

+#define TT_DESCRIPTOR_TYPE_COARSE   ((1UL << 0) | (1UL << 4))

+#define TT_DESCRIPTOR_TYPE_SECTION  ((2UL << 0) | (1UL << 4))

+#define TT_DESCRIPTOR_TYPE_FINE     ((3UL << 0) | (1UL << 4))

+

+// Section descriptor definitions

+#define TT_DESCRIPTOR_SECTION_SIZE                              (0x00100000)

+

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK                 (3UL <<  2)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED  (0UL <<  2)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_BUFFERED    (1UL <<  2)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH        (2UL <<  2)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK           (3UL <<  2)

+

+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_MASK            (3UL << 10)

+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_NONE            (1UL << 10)

+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_ONLY       (2UL << 10)

+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE      (3UL << 10)

+

+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK                       (0x0FUL << 5)

+#define TT_DESCRIPTOR_SECTION_DOMAIN(a)                         (((a) & 0xF) << 5)

+

+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK                 (0xFFF00000)

+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a)                   (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)

+

+#define TT_DESCRIPTOR_SECTION_WRITE_BACK          (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \

+                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                    | \

+                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK      | \

+                                                   TT_DESCRIPTOR_TYPE_SECTION)

+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH       (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \

+                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                    | \

+                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH   | \

+                                                   TT_DESCRIPTOR_TYPE_SECTION)

+#define TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE     | \

+                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                        | \

+                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED | \

+                                                   TT_DESCRIPTOR_TYPE_SECTION)

+

+#endif // __ARM926EJ_S_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmAemV8.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmAemV8.h
new file mode 100644
index 0000000..a64a921
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmAemV8.h
@@ -0,0 +1,21 @@
+/** @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.

+

+**/

+

+#ifndef __ARM_AEM_V8_H__

+#define __ARM_AEM_V8_H__

+

+#include <Chipset/AArch64.h>

+

+#endif //__ARM_AEM_V8_H__

+

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmArchTimer.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmArchTimer.h
new file mode 100644
index 0000000..1caad3d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmArchTimer.h
@@ -0,0 +1,139 @@
+/** @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.

+*

+**/

+

+#ifndef __ARM_ARCH_TIMER_H_

+#define __ARM_ARCH_TIMER_H_

+

+UINTN

+EFIAPI

+ArmReadCntFrq (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntFrq (

+  UINTN   FreqInHz

+  );

+

+UINT64

+EFIAPI

+ArmReadCntPct (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadCntkCtl (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntkCtl (

+  UINTN   Val

+  );

+

+UINTN

+EFIAPI

+ArmReadCntpTval (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntpTval (

+  UINTN   Val

+  );

+

+UINTN

+EFIAPI

+ArmReadCntpCtl (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntpCtl (

+  UINTN   Val

+  );

+

+UINTN

+EFIAPI

+ArmReadCntvTval (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntvTval (

+  UINTN   Val

+  );

+

+UINTN

+EFIAPI

+ArmReadCntvCtl (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntvCtl (

+  UINTN   Val

+  );

+

+UINT64

+EFIAPI

+ArmReadCntvCt (

+  VOID

+  );

+

+UINT64

+EFIAPI

+ArmReadCntpCval (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntpCval (

+  UINT64   Val

+  );

+

+UINT64

+EFIAPI

+ArmReadCntvCval (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntvCval (

+  UINT64   Val

+  );

+

+UINT64

+EFIAPI

+ArmReadCntvOff (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCntvOff (

+  UINT64   Val

+  );

+

+#endif // __ARM_ARCH_TIMER_H_

+

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA15.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA15.h
new file mode 100644
index 0000000..5f71567
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA15.h
@@ -0,0 +1,25 @@
+/** @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.

+

+**/

+

+#ifndef __ARM_CORTEX_A15_H__

+#define __ARM_CORTEX_A15_H__

+

+#include <Chipset/ArmV7.h>

+

+//

+// Cortex A15 feature bit definitions

+//

+#define A15_FEATURE_SMP     (1<<6)

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA5x.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA5x.h
new file mode 100644
index 0000000..ba3d519
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA5x.h
@@ -0,0 +1,50 @@
+/** @file

+

+  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __ARM_CORTEX_A5x_H__

+#define __ARM_CORTEX_A5x_H__

+

+//

+// Cortex A5x feature bit definitions

+//

+#define A5X_FEATURE_SMP     (1 << 6)

+

+//

+// Helper functions to access CPU Extended Control Register

+//

+UINT64

+EFIAPI

+ArmReadCpuExCr (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCpuExCr (

+  IN  UINT64 Val

+  );

+

+VOID

+EFIAPI

+ArmSetCpuExCrBit (

+  IN  UINT64    Bits

+  );

+

+VOID

+EFIAPI

+ArmUnsetCpuExCrBit (

+  IN  UINT64    Bits

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA9.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA9.h
new file mode 100644
index 0000000..af9a300
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA9.h
@@ -0,0 +1,65 @@
+/** @file

+

+  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_CORTEX_A9_H__

+#define __ARM_CORTEX_A9_H__

+

+#include <Chipset/ArmV7.h>

+

+//

+// Cortex A9 feature bit definitions

+//

+#define A9_FEATURE_PARITY  (1<<9)

+#define A9_FEATURE_AOW     (1<<8)

+#define A9_FEATURE_EXCL    (1<<7)

+#define A9_FEATURE_SMP     (1<<6)

+#define A9_FEATURE_FOZ     (1<<3)

+#define A9_FEATURE_DPREF   (1<<2)

+#define A9_FEATURE_HINT    (1<<1)

+#define A9_FEATURE_FWD     (1<<0)

+

+//

+// Cortex A9 Watchdog

+//

+#define ARM_A9_WATCHDOG_REGION           0x600

+

+#define ARM_A9_WATCHDOG_LOAD_REGISTER    0x20

+#define ARM_A9_WATCHDOG_CONTROL_REGISTER 0x28

+

+#define ARM_A9_WATCHDOG_WATCHDOG_MODE    (1 << 3)

+#define ARM_A9_WATCHDOG_TIMER_MODE       (0 << 3)

+#define ARM_A9_WATCHDOG_SINGLE_SHOT      (0 << 1)

+#define ARM_A9_WATCHDOG_AUTORELOAD       (1 << 1)

+#define ARM_A9_WATCHDOG_ENABLE           1

+

+//

+// SCU register offsets & masks

+//

+#define A9_SCU_CONTROL_OFFSET       0x0

+#define A9_SCU_CONFIG_OFFSET        0x4

+#define A9_SCU_INVALL_OFFSET        0xC

+#define A9_SCU_FILT_START_OFFSET    0x40

+#define A9_SCU_FILT_END_OFFSET      0x44

+#define A9_SCU_SACR_OFFSET          0x50

+#define A9_SCU_SSACR_OFFSET         0x54

+

+

+UINTN

+EFIAPI

+ArmGetScuBaseAddress (

+  VOID

+  );

+

+#endif

+

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7.h
new file mode 100644
index 0000000..ceb3217
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7.h
@@ -0,0 +1,127 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __ARM_V7_H__

+#define __ARM_V7_H__

+

+#include <Chipset/ArmV7Mmu.h>

+#include <Chipset/ArmArchTimer.h>

+

+// ARM Interrupt ID in Exception Table

+#define ARM_ARCH_EXCEPTION_IRQ            EXCEPT_ARM_IRQ

+

+// ID_PFR1 - ARM Processor Feature Register 1 definitions

+#define ARM_PFR1_SEC        (0xFUL << 4)

+#define ARM_PFR1_TIMER      (0xFUL << 16)

+#define ARM_PFR1_GIC        (0xFUL << 28)

+

+// Domain Access Control Register

+#define DOMAIN_ACCESS_CONTROL_MASK(a)     (3UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_NONE(a)     (0UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_CLIENT(a)   (1UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))

+#define DOMAIN_ACCESS_CONTROL_MANAGER(a)  (3UL << (2 * (a)))

+

+// CPSR - Coprocessor Status Register definitions

+#define CPSR_MODE_USER       0x10

+#define CPSR_MODE_FIQ        0x11

+#define CPSR_MODE_IRQ        0x12

+#define CPSR_MODE_SVC        0x13

+#define CPSR_MODE_ABORT      0x17

+#define CPSR_MODE_HYP        0x1A

+#define CPSR_MODE_UNDEFINED  0x1B

+#define CPSR_MODE_SYSTEM     0x1F

+#define CPSR_MODE_MASK       0x1F

+#define CPSR_ASYNC_ABORT     (1 << 8)

+#define CPSR_IRQ             (1 << 7)

+#define CPSR_FIQ             (1 << 6)

+

+

+// CPACR - Coprocessor Access Control Register definitions

+#define CPACR_CP_DENIED(cp)     0x00

+#define CPACR_CP_PRIV(cp)       ((0x1 << ((cp) << 1)) & 0x0FFFFFFF)

+#define CPACR_CP_FULL(cp)       ((0x3 << ((cp) << 1)) & 0x0FFFFFFF)

+#define CPACR_ASEDIS            (1 << 31)

+#define CPACR_D32DIS            (1 << 30)

+#define CPACR_CP_FULL_ACCESS    0x0FFFFFFF

+

+// NSACR - Non-Secure Access Control Register definitions

+#define NSACR_CP(cp)            ((1 << (cp)) & 0x3FFF)

+#define NSACR_NSD32DIS          (1 << 14)

+#define NSACR_NSASEDIS          (1 << 15)

+#define NSACR_PLE               (1 << 16)

+#define NSACR_TL                (1 << 17)

+#define NSACR_NS_SMP            (1 << 18)

+#define NSACR_RFR               (1 << 19)

+

+// SCR - Secure Configuration Register definitions

+#define SCR_NS                  (1 << 0)

+#define SCR_IRQ                 (1 << 1)

+#define SCR_FIQ                 (1 << 2)

+#define SCR_EA                  (1 << 3)

+#define SCR_FW                  (1 << 4)

+#define SCR_AW                  (1 << 5)

+

+// MIDR - Main ID Register definitions

+#define ARM_CPU_TYPE_MASK       0xFFF

+#define ARM_CPU_TYPE_AEMv8      0xD0F

+#define ARM_CPU_TYPE_A53        0xD03

+#define ARM_CPU_TYPE_A57        0xD07

+#define ARM_CPU_TYPE_A15        0xC0F

+#define ARM_CPU_TYPE_A9         0xC09

+#define ARM_CPU_TYPE_A5         0xC05

+

+#define ARM_CPU_REV_MASK        ((0xF << 20) | (0xF) )

+#define ARM_CPU_REV(rn, pn)     ((((rn) & 0xF) << 20) | ((pn) & 0xF))

+

+#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 5)-1)

+

+VOID

+EFIAPI

+ArmEnableSWPInstruction (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadCbar (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadTpidrurw (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteTpidrurw (

+  UINTN Value

+  );

+

+UINT32

+EFIAPI

+ArmReadNsacr (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteNsacr (

+  IN  UINT32   Nsacr

+  );

+

+#endif // __ARM_V7_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7Mmu.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7Mmu.h
new file mode 100644
index 0000000..24ab175
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7Mmu.h
@@ -0,0 +1,231 @@
+/** @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.

+*

+**/

+

+#ifndef __ARMV7_MMU_H_

+#define __ARMV7_MMU_H_

+

+#define TTBR_NOT_OUTER_SHAREABLE             BIT5

+#define TTBR_RGN_OUTER_NON_CACHEABLE         0

+#define TTBR_RGN_OUTER_WRITE_BACK_ALLOC      BIT3

+#define TTBR_RGN_OUTER_WRITE_THROUGH         BIT4

+#define TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC   (BIT3|BIT4)

+#define TTBR_SHAREABLE                       BIT1

+#define TTBR_NON_SHAREABLE                   0

+#define TTBR_INNER_CACHEABLE                 BIT0

+#define TTBR_NON_INNER_CACHEABLE             BIT0

+#define TTBR_RGN_INNER_NON_CACHEABLE         0

+#define TTBR_RGN_INNER_WRITE_BACK_ALLOC      BIT6

+#define TTBR_RGN_INNER_WRITE_THROUGH         BIT0

+#define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC   (BIT0|BIT6)

+

+#define TTBR_WRITE_THROUGH_NO_ALLOC     ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )

+#define TTBR_WRITE_BACK_NO_ALLOC        ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC )

+#define TTBR_NON_CACHEABLE              ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE )

+#define TTBR_WRITE_BACK_ALLOC           ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )

+

+

+#define TRANSLATION_TABLE_SECTION_COUNT                 4096

+#define TRANSLATION_TABLE_SECTION_SIZE                  (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)

+#define TRANSLATION_TABLE_SECTION_ALIGNMENT             (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)

+#define TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK        (TRANSLATION_TABLE_SECTION_ALIGNMENT - 1)

+

+#define TRANSLATION_TABLE_PAGE_COUNT                 256

+#define TRANSLATION_TABLE_PAGE_SIZE                  (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)

+#define TRANSLATION_TABLE_PAGE_ALIGNMENT             (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)

+#define TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK        (TRANSLATION_TABLE_PAGE_ALIGNMENT - 1)

+

+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))

+

+// Translation table descriptor types

+#define TT_DESCRIPTOR_SECTION_TYPE_MASK         ((1UL << 18) | (3UL << 0))

+#define TT_DESCRIPTOR_SECTION_TYPE_FAULT        (0UL << 0)

+#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE   (1UL << 0)

+#define TT_DESCRIPTOR_SECTION_TYPE_SECTION      ((0UL << 18) | (2UL << 0))

+#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))

+#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE)

+

+// Translation table descriptor types

+#define TT_DESCRIPTOR_PAGE_TYPE_MASK         (3UL << 0)

+#define TT_DESCRIPTOR_PAGE_TYPE_FAULT        (0UL << 0)

+#define TT_DESCRIPTOR_PAGE_TYPE_PAGE         (2UL << 0)

+#define TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN      (3UL << 0)

+#define TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE    (1UL << 0)

+

+// Section descriptor definitions

+#define TT_DESCRIPTOR_SECTION_SIZE                              (0x00100000)

+

+#define TT_DESCRIPTOR_SECTION_NS_MASK                           (1UL << 19)

+#define TT_DESCRIPTOR_SECTION_NS                                (1UL << 19)

+

+#define TT_DESCRIPTOR_SECTION_NG_MASK                           (1UL << 17)

+#define TT_DESCRIPTOR_SECTION_NG_GLOBAL                         (0UL << 17)

+#define TT_DESCRIPTOR_SECTION_NG_LOCAL                          (1UL << 17)

+

+#define TT_DESCRIPTOR_PAGE_NG_MASK                              (1UL << 11)

+#define TT_DESCRIPTOR_PAGE_NG_GLOBAL                            (0UL << 11)

+#define TT_DESCRIPTOR_PAGE_NG_LOCAL                             (1UL << 11)

+

+#define TT_DESCRIPTOR_SECTION_S_MASK                            (1UL << 16)

+#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      (0UL << 16)

+#define TT_DESCRIPTOR_SECTION_S_SHARED                          (1UL << 16)

+

+#define TT_DESCRIPTOR_PAGE_S_MASK                               (1UL << 10)

+#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED                         (0UL << 10)

+#define TT_DESCRIPTOR_PAGE_S_SHARED                             (1UL << 10)

+

+#define TT_DESCRIPTOR_SECTION_AP_MASK                           ((1UL << 15) | (3UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_NO_NO                          ((0UL << 15) | (0UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RW_NO                          ((0UL << 15) | (1UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RW_RO                          ((0UL << 15) | (2UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RW_RW                          ((0UL << 15) | (3UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RO_NO                          ((1UL << 15) | (1UL << 10))

+#define TT_DESCRIPTOR_SECTION_AP_RO_RO                          ((1UL << 15) | (3UL << 10))

+

+#define TT_DESCRIPTOR_PAGE_AP_MASK                              ((1UL << 9) | (3UL << 4))

+#define TT_DESCRIPTOR_PAGE_AP_NO_NO                             ((0UL << 9) | (0UL << 4))

+#define TT_DESCRIPTOR_PAGE_AP_RW_NO                             ((0UL << 9) | (1UL << 4))

+#define TT_DESCRIPTOR_PAGE_AP_RW_RO                             ((0UL << 9) | (2UL << 4))

+#define TT_DESCRIPTOR_PAGE_AP_RW_RW                             ((0UL << 9) | (3UL << 4))

+#define TT_DESCRIPTOR_PAGE_AP_RO_NO                             ((1UL << 9) | (1UL << 4))

+#define TT_DESCRIPTOR_PAGE_AP_RO_RO                             ((1UL << 9) | (3UL << 4))

+

+#define TT_DESCRIPTOR_SECTION_XN_MASK                           (0x1UL << 4)

+#define TT_DESCRIPTOR_PAGE_XN_MASK                              (0x1UL << 0)

+#define TT_DESCRIPTOR_LARGEPAGE_XN_MASK                         (0x1UL << 15)

+

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK                   ((3UL << 12) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK                      (1UL << 3)

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 12) | (0UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 12) | (0UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC    ((0UL << 12) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE          ((1UL << 12) | (0UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 12) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 12) | (0UL << 3) | (0UL << 2))

+

+#define TT_DESCRIPTOR_PAGE_SIZE                               (0x00001000)

+

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK                   ((3UL << 6) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHEABLE_MASK                       (1UL << 3)

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 6) | (0UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 6) | (0UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 6) | (1UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC    ((0UL << 6) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE          ((1UL << 6) | (0UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 6) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 6) | (0UL << 3) | (0UL << 2))

+

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK                   ((3UL << 12) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 12) | (0UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 12) | (0UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC    ((0UL << 12) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_CACHEABLE          ((1UL << 12) | (0UL << 3) | (0UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 12) | (1UL << 3) | (1UL << 2))

+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 12) | (0UL << 3) | (0UL << 2))

+

+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)

+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)

+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)

+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc,IsLargePage)      ((IsLargePage)? \

+                                                                    ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) << 11) & TT_DESCRIPTOR_LARGEPAGE_XN_MASK):    \

+                                                                    ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK))

+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc,IsLargePage)      (IsLargePage? \

+                                                                    (((Desc) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK): \

+                                                                    (((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))))

+

+#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc)                  ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK)

+

+#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc,IsLargePage)      (IsLargePage? \

+                                                                    (((Desc) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK): \

+                                                                    (((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2)))))

+

+#define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK                (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \

+                                                             TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \

+                                                             TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK)

+

+#define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK                   (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \

+                                                             TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_XN_MASK | \

+                                                             TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK)

+

+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK                       (0x0FUL << 5)

+#define TT_DESCRIPTOR_SECTION_DOMAIN(a)                         (((a) & 0x0FUL) << 5)

+

+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK                 (0xFFF00000)

+#define TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK            (0xFFFFFC00)

+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a)                   ((a) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)

+#define TT_DESCRIPTOR_SECTION_BASE_SHIFT                        20

+

+#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK                 (0xFFFFF000)

+#define TT_DESCRIPTOR_PAGE_INDEX_MASK                        (0x000FF000)

+#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a)                   ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK)

+#define TT_DESCRIPTOR_PAGE_BASE_SHIFT                        12

+

+#define TT_DESCRIPTOR_SECTION_WRITE_BACK(NonSecure)         (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \

+                                                            ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \

+                                                            TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                            TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                            TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                            TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                            TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)

+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(NonSecure)      (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \

+                                                            ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \

+                                                            TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                            TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                            TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                            TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                            TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)

+#define TT_DESCRIPTOR_SECTION_DEVICE(NonSecure)             (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \

+                                                            ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \

+                                                            TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                            TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                            TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                            TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                            TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)

+#define TT_DESCRIPTOR_SECTION_UNCACHED(NonSecure)          (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \

+                                                           ((NonSecure) ?  TT_DESCRIPTOR_SECTION_NS : 0)    | \

+                                                           TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \

+                                                           TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \

+                                                           TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \

+                                                           TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \

+                                                           TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)

+

+#define TT_DESCRIPTOR_PAGE_WRITE_BACK              (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \

+                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \

+                                                        TT_DESCRIPTOR_PAGE_S_NOT_SHARED                                                   | \

+                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \

+                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC)

+#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH           (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \

+                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \

+                                                        TT_DESCRIPTOR_PAGE_S_NOT_SHARED                                                   | \

+                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \

+                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)

+#define TT_DESCRIPTOR_PAGE_DEVICE                  (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \

+                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \

+                                                        TT_DESCRIPTOR_PAGE_S_NOT_SHARED                                                   | \

+                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \

+                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE)

+#define TT_DESCRIPTOR_PAGE_UNCACHED                (TT_DESCRIPTOR_PAGE_TYPE_PAGE                                                           | \

+                                                        TT_DESCRIPTOR_PAGE_NG_GLOBAL                                                      | \

+                                                        TT_DESCRIPTOR_PAGE_S_NOT_SHARED                                                   | \

+                                                        TT_DESCRIPTOR_PAGE_AP_RW_RW                                                       | \

+                                                        TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE)

+

+UINT32

+ConvertSectionAttributesToPageAttributes (

+  IN UINT32   SectionAttributes,

+  IN BOOLEAN  IsLargePage

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Guid/ArmMpCoreInfo.h b/uefi/linaro-edk2/ArmPkg/Include/Guid/ArmMpCoreInfo.h
new file mode 100644
index 0000000..07dec5d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Guid/ArmMpCoreInfo.h
@@ -0,0 +1,66 @@
+/** @file

+*

+*  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_MP_CORE_INFO_GUID_H_

+#define __ARM_MP_CORE_INFO_GUID_H_

+

+#define MAX_CPUS_PER_MPCORE_SYSTEM    0x04

+#define SCU_CONFIG_REG_OFFSET         0x04

+#define MPIDR_U_BIT_MASK              0x40000000

+

+typedef struct {

+  UINT32                ClusterId;

+  UINT32                CoreId;

+

+  // MP Core Mailbox

+  EFI_PHYSICAL_ADDRESS  MailboxSetAddress;

+  EFI_PHYSICAL_ADDRESS  MailboxGetAddress;

+  EFI_PHYSICAL_ADDRESS  MailboxClearAddress;

+  UINT64                MailboxClearValue;

+} ARM_CORE_INFO;

+

+typedef struct{

+        UINT64   Signature;

+        UINT32   Length;

+        UINT32   Revision;

+        UINT64   OemId;

+        UINT64   OemTableId;

+        UINTN    OemRevision;

+        UINTN    CreatorId;

+        UINTN    CreatorRevision;

+        EFI_GUID Identifier;

+        UINTN    DataLen;

+} ARM_PROCESSOR_TABLE_HEADER;

+

+typedef struct {

+        ARM_PROCESSOR_TABLE_HEADER   Header;

+        UINTN                        NumberOfEntries;

+        ARM_CORE_INFO                *ArmCpus;

+} ARM_PROCESSOR_TABLE;

+

+

+#define ARM_MP_CORE_INFO_GUID \

+  { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }

+

+#define EFI_ARM_PROCESSOR_TABLE_SIGNATURE        SIGNATURE_64 ('C', 'P', 'U', 'T', 'A', 'B', 'L', 'E')

+#define EFI_ARM_PROCESSOR_TABLE_REVISION         0x00010000 //1.0

+#define EFI_ARM_PROCESSOR_TABLE_OEM_ID           SIGNATURE_64('A','R','M',' ', 'L', 't', 'd', ' ')

+#define EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID     SIGNATURE_64('V', 'E', 'R', 'S', 'A', 'T', 'I', 'L')

+#define EFI_ARM_PROCESSOR_TABLE_OEM_REVISION     0x00000001

+#define EFI_ARM_PROCESSOR_TABLE_CREATOR_ID       0xA5A5A5A5

+#define EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION 0x01000001

+

+extern EFI_GUID gArmMpCoreInfoGuid;

+

+#endif /* MPCOREINFO_H_ */

diff --git a/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
new file mode 100644
index 0000000..593a3ce
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
@@ -0,0 +1,96 @@
+/** @file

+*

+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+*

+*  This program and the accompanying materials

+*  are licensed and made available under the terms and conditions of the BSD License

+*  which accompanies this distribution.  The full text of the license may be found at

+*  http://opensource.org/licenses/bsd-license.php

+*

+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+*

+**/

+

+#ifndef __ARM_STD_SMC_H__

+#define __ARM_STD_SMC_H__

+

+/*

+ * SMC function IDs for Standard Service queries

+ */

+

+#define ARM_SMC_ID_STD_CALL_COUNT     0x8400ff00

+#define ARM_SMC_ID_STD_UID            0x8400ff01

+/*                                    0x8400ff02 is reserved */

+#define ARM_SMC_ID_STD_REVISION       0x8400ff03

+

+/*

+ * The 'Standard Service Call UID' is supposed to return the Standard

+ * Service UUID. This is a 128-bit value.

+ */

+#define ARM_SMC_STD_UUID0       0x108d905b

+#define ARM_SMC_STD_UUID1       0x47e8f863

+#define ARM_SMC_STD_UUID2       0xfbc02dae

+#define ARM_SMC_STD_UUID3       0xe2f64156

+

+/*

+ * ARM Standard Service Calls revision numbers

+ * The current revision is:  0.1

+ */

+#define ARM_SMC_STD_REVISION_MAJOR    0x0

+#define ARM_SMC_STD_REVISION_MINOR    0x1

+

+/*

+ * Power State Coordination Interface (PSCI) calls cover a subset of the

+ * Standard Service Call range.

+ * The list below is not exhaustive.

+ */

+#define ARM_SMC_ID_PSCI_VERSION                0x84000000

+#define ARM_SMC_ID_PSCI_CPU_SUSPEND_AARCH64    0xc4000001

+#define ARM_SMC_ID_PSCI_CPU_SUSPEND_AARCH32    0x84000001

+#define ARM_SMC_ID_PSCI_CPU_OFF                0x84000002

+#define ARM_SMC_ID_PSCI_CPU_ON_AARCH64         0xc4000003

+#define ARM_SMC_ID_PSCI_CPU_ON_AARCH32         0x84000003

+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_AARCH64  0xc4000004

+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_AARCH32  0x84000004

+#define ARM_SMC_ID_PSCI_MIGRATE_AARCH64        0xc4000005

+#define ARM_SMC_ID_PSCI_MIGRATE_AARCH32        0x84000005

+#define ARM_SMC_ID_PSCI_SYSTEM_OFF             0x84000008

+#define ARM_SMC_ID_PSCI_SYSTEM_RESET           0x84000009

+

+/* The current PSCI version is:  0.2 */

+#define ARM_SMC_PSCI_VERSION_MAJOR  0

+#define ARM_SMC_PSCI_VERSION_MINOR  2

+#define ARM_SMC_PSCI_VERSION  \

+  ((ARM_SMC_PSCI_VERSION_MAJOR << 16) | ARM_SMC_PSCI_VERSION_MINOR)

+

+/* PSCI return error codes */

+#define ARM_SMC_PSCI_RET_SUCCESS            0

+#define ARM_SMC_PSCI_RET_NOT_SUPPORTED      -1

+#define ARM_SMC_PSCI_RET_INVALID_PARAMS     -2

+#define ARM_SMC_PSCI_RET_DENIED             -3

+#define ARM_SMC_PSCI_RET_ALREADY_ON         -4

+#define ARM_SMC_PSCI_RET_ON_PENDING         -5

+#define ARM_SMC_PSCI_RET_INTERN_FAIL        -6

+#define ARM_SMC_PSCI_RET_NOT_PRESENT        -7

+#define ARM_SMC_PSCI_RET_DISABLED           -8

+

+#define ARM_SMC_PSCI_TARGET_CPU32(Aff2, Aff1, Aff0) \

+  ((((Aff2) & 0xFF) << 16) | (((Aff1) & 0xFF) << 8) | ((Aff0) & 0xFF))

+

+#define ARM_SMC_PSCI_TARGET_CPU64(Aff3, Aff2, Aff1, Aff0) \

+  ((((Aff3) & 0xFFULL) << 32) | (((Aff2) & 0xFF) << 16) | (((Aff1) & 0xFF) << 8) | ((Aff0) & 0xFF))

+

+#define ARM_SMC_PSCI_TARGET_GET_AFF0(TargetId)  ((TargetId) & 0xFF)

+#define ARM_SMC_PSCI_TARGET_GET_AFF1(TargetId)  (((TargetId) >> 8) & 0xFF)

+

+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_0    0

+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_1    1

+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_2    2

+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_3    3

+

+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_ON          0

+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_OFF         1

+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_ON_PENDING  2

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
new file mode 100644
index 0000000..71b4327
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
@@ -0,0 +1,161 @@
+/** @file

+*

+*  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.

+*

+**/

+

+#ifndef __ARM_TRUSTZONE_SMC_H__

+#define __ARM_TRUSTZONE_SMC_H__

+

+#define ARM_TRUSTZONE_UID_4LETTERID   0x1

+#define ARM_TRUSTZONE_UID_MD5         0x2

+

+#define ARM_TRUSTZONE_ARM_UID         0x40524d48 // "ARMH"

+

+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,Region)       (((UINTN)(Rx) >= (UINTN)ARM_TRUSTZONE_##Region##_SMC_ID_START) && ((UINTN)(Rx) <= (UINTN)ARM_TRUSTZONE_##Region##_SMC_ID_END))

+

+#define IS_ARM_TRUSTZONE_DEPRECIATED_SMC(Rx)            ((UINTN)(Rx) <= (UINTN)ARM_TRUSTZONE_DEPRECIATED_SMC_ID_END)

+#define IS_ARM_TRUSTZONE_TRUSTED_OS_SMC(Rx)             IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,TRUSTED_OS)

+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC(Rx)               IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,ARM_FAST)

+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC(Rx)               IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,SIP_FAST)

+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC(Rx)               IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,ODM_FAST)

+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC(Rx)               IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,OEM_FAST)

+#define IS_ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC(Rx)      IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,TRUSTED_USER_FAST)

+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC(Rx)        IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,TRUSTED_OS_FAST)

+

+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,Region) ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_PRESENCE)

+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,Region)      (((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID)   || \

+                                                               ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+1) || \

+                                                               ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+2) || \

+                                                               ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+3) || \

+                                                               ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+4))

+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,Region) (((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_REVISION)   || \

+                                                               ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_REVISION+1))

+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,Region)      (((Rx) >= ARM_TRUSTZONE_##Region##_SMC_ID_RPC_START) && \

+                                                               ((Rx) <= ARM_TRUSTZONE_##Region##_SMC_ID_RPC_END))

+

+#define ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,Region)       ((Rx) - ARM_TRUSTZONE_##Region##_SMC_ID_UID)

+#define ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,Region)  ((Rx) - ARM_TRUSTZONE_##Region##_SMC_ID_REVISION)

+#define ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,Region)       ((Rx) - ARM_TRUSTZONE_##Region##_SMC_ID_RPC_START)

+

+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_RPC_INDEX(Rx)       ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,TRUSTED_OS)

+

+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,ARM_FAST)

+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,ARM_FAST)

+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_REVISION(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,ARM_FAST)

+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,ARM_FAST)

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,ARM_FAST)

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_REVISION_INDEX(Rx)    ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,ARM_FAST)

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,ARM_FAST)

+

+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_PRESENCE(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,ODM_FAST)

+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_UID(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,ODM_FAST)

+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_REVISION(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,ODM_FAST)

+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,ODM_FAST)

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_UID_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,ODM_FAST)

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_REVISION_INDEX(Rx)    ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,ODM_FAST)

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,ODM_FAST)

+

+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_PRESENCE(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,OEM_FAST)

+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_UID(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,OEM_FAST)

+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_REVISION(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,OEM_FAST)

+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,OEM_FAST)

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_UID_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,OEM_FAST)

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_REVISION_INDEX(Rx)    ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,OEM_FAST)

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,OEM_FAST)

+

+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_PRESENCE(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,SIP_FAST)

+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_UID(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,SIP_FAST)

+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_REVISION(Rx)       IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,SIP_FAST)

+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC(Rx)            IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,SIP_FAST)

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_UID_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,SIP_FAST)

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_REVISION_INDEX(Rx)    ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,SIP_FAST)

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC_INDEX(Rx)         ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,SIP_FAST)

+

+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_RPC_INDEX(Rx)    ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,TRUSTED_USER_FAST)

+

+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_PRESENCE(Rx)    IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,TRUSTED_OS_FAST)

+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_UID(Rx)         IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,TRUSTED_OS_FAST)

+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_REVISION(Rx)    IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,TRUSTED_OS_FAST)

+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC(Rx)         IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,TRUSTED_OS_FAST)

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_UID_INDEX(Rx)      ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,TRUSTED_OS_FAST)

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_REVISION_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,TRUSTED_OS_FAST)

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC_INDEX(Rx)      ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,TRUSTED_OS_FAST)

+

+

+#define ARM_TRUSTZONE_DEPRECIATED_SMC_ID_START          0x00000000

+#define ARM_TRUSTZONE_DEPRECIATED_SMC_ID_END            0x01FFFFFF

+

+

+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_START           0x02000000

+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_END             0x1FFFFFFF

+

+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_RPC_START       0x02000000

+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_RPC_END         0x1FFFFFFF

+

+

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_START             0x80000000

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_END               0x80FFFFFF

+

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC_START         0x80000000

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC_END           0x80FFFEFF

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE          0x80FFFF00

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID               0x80FFFF10

+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_REVISION          0x80FFFF20

+

+

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_START             0x81000000

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_END               0x81FFFFFF

+

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC_START         0x81000000

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC_END           0x81FFFEFF

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_PRESENCE          0x81FFFF00

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_UID               0x81FFFF10

+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_REVISION          0x81FFFF20

+

+

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_START             0x82000000

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_END               0x82FFFFFF

+

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC_START         0x82000000

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC_END           0x82FFFEFF

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_PRESENCE          0x82FFFF00

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_UID               0x82FFFF10

+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_REVISION          0x82FFFF20

+

+

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_START             0x83000000

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_END               0x83FFFFFF

+

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC_START         0x83000000

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC_END           0x83FFFEFF

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_PRESENCE          0x83FFFF00

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_UID               0x83FFFF10

+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_REVISION          0x83FFFF20

+

+

+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_START    0xF0000000

+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_END      0xF1FFFFFF

+

+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_RPC_START  0xF0000000

+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_RPC_END    0xF1FFFEFF

+

+

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_START      0xF2000000

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_END        0xFFFFFFFF

+

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC_START  0xF2000000

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC_END    0xFFFFFEFF

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_PRESENCE   0xF2FFFF00

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_UID        0xF2FFFF10

+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_REVISION   0xF2FFFF20

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmArchTimer.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmArchTimer.h
new file mode 100644
index 0000000..876c1f6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmArchTimer.h
@@ -0,0 +1,55 @@
+/** @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.

+

+**/

+

+#ifndef __ARM_ARCH_TIMER_H__

+#define __ARM_ARCH_TIMER_H__

+

+#define ARM_ARCH_TIMER_ENABLE           (1 << 0)

+#define ARM_ARCH_TIMER_IMASK            (1 << 1)

+#define ARM_ARCH_TIMER_ISTATUS          (1 << 2)

+

+typedef enum {

+  CntFrq = 0,

+  CntPct,

+  CntkCtl,

+  CntpTval,

+  CntpCtl,

+  CntvTval,

+  CntvCtl,

+  CntvCt,

+  CntpCval,

+  CntvCval,

+  CntvOff,

+  CnthCtl,

+  CnthpTval,

+  CnthpCtl,

+  CnthpCval,

+  RegMaximum

+} ARM_ARCH_TIMER_REGS;

+

+VOID

+EFIAPI

+ArmArchTimerReadReg (

+  IN   ARM_ARCH_TIMER_REGS   Reg,

+  OUT  VOID                  *DstBuf

+  );

+

+VOID

+EFIAPI

+ArmArchTimerWriteReg (

+  IN   ARM_ARCH_TIMER_REGS   Reg,

+  IN   VOID                  *SrcBuf

+  );

+

+#endif // __ARM_ARCH_TIMER_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmCpuLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmCpuLib.h
new file mode 100644
index 0000000..0c41599
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmCpuLib.h
@@ -0,0 +1,28 @@
+/** @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.

+

+**/

+

+#ifndef __ARMCPU_LIB__

+#define __ARMCPU_LIB__

+

+VOID

+ArmCpuSetup (

+  IN  UINTN         MpId

+  );

+

+VOID

+ArmCpuSetupSmpNonSecure (

+  IN  UINTN         MpId

+  );

+

+#endif // __ARMCPU_LIB__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmDisassemblerLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmDisassemblerLib.h
new file mode 100644
index 0000000..d6a493f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmDisassemblerLib.h
@@ -0,0 +1,43 @@
+/** @file

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __ARM_DISASSEBLER_LIB_H__

+#define __ARM_DISASSEBLER_LIB_H__

+

+/**

+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to

+  point to next instructin.

+

+  We cheat and only decode instructions that access

+  memory. If the instruction is not found we dump the instruction in hex.

+

+  @param  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.

+  @param  Thumb         TRUE for Thumb(2), FALSE for ARM instruction stream

+  @param  Extended      TRUE dump hex for instruction too.

+  @param  ItBlock       Size of IT Block

+  @param  Buf           Buffer to sprintf disassembly into.

+  @param  Size          Size of Buf in bytes.

+

+**/

+VOID

+DisassembleInstruction (

+  IN  UINT8     **OpCodePtr,

+  IN  BOOLEAN   Thumb,

+  IN  BOOLEAN   Extended,

+  IN OUT UINT32 *ItBlock,

+  OUT CHAR8     *Buf,

+  OUT UINTN     Size

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGenericTimerCounterLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGenericTimerCounterLib.h
new file mode 100644
index 0000000..805025b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGenericTimerCounterLib.h
@@ -0,0 +1,85 @@
+/** @file

+

+  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>

+  Copyright (c) 2014, 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.

+

+**/

+

+#ifndef __ARM_GENERIC_TIMER_COUNTER_LIB_H__

+#define __ARM_GENERIC_TIMER_COUNTER_LIB_H__

+

+VOID

+EFIAPI

+ArmGenericTimerEnableTimer (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGenericTimerDisableTimer (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerFreq (

+  IN   UINTN  FreqInHz

+  );

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerFreq (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerVal (

+  IN   UINTN   Value

+  );

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerVal (

+  VOID

+  );

+

+UINT64

+EFIAPI

+ArmGenericTimerGetSystemCount (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerCtrlReg (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerCtrlReg (

+  UINTN Value

+  );

+

+UINT64

+EFIAPI

+ArmGenericTimerGetCompareVal (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmGenericTimerSetCompareVal (

+  IN   UINT64   Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGicLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGicLib.h
new file mode 100644
index 0000000..e2a4818
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGicLib.h
@@ -0,0 +1,234 @@
+/** @file

+*

+*  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 __ARMGIC_H

+#define __ARMGIC_H

+

+//

+// GIC definitions

+//

+typedef enum {

+  ARM_GIC_ARCH_REVISION_2,

+  ARM_GIC_ARCH_REVISION_3

+} ARM_GIC_ARCH_REVISION;

+

+//

+// GIC Distributor

+//

+#define ARM_GIC_ICDDCR          0x000 // Distributor Control Register

+#define ARM_GIC_ICDICTR         0x004 // Interrupt Controller Type Register

+#define ARM_GIC_ICDIIDR         0x008 // Implementer Identification Register

+

+// Each reg base below repeats for Number of interrupts / 4 (see GIC spec)

+#define ARM_GIC_ICDISR          0x080 // Interrupt Security Registers

+#define ARM_GIC_ICDISER         0x100 // Interrupt Set-Enable Registers

+#define ARM_GIC_ICDICER         0x180 // Interrupt Clear-Enable Registers

+#define ARM_GIC_ICDSPR          0x200 // Interrupt Set-Pending Registers

+#define ARM_GIC_ICDICPR         0x280 // Interrupt Clear-Pending Registers

+#define ARM_GIC_ICDABR          0x300 // Active Bit Registers

+

+// Each reg base below repeats for Number of interrupts / 4

+#define ARM_GIC_ICDIPR          0x400 // Interrupt Priority Registers

+

+// Each reg base below repeats for Number of interrupts

+#define ARM_GIC_ICDIPTR         0x800 // Interrupt Processor Target Registers

+#define ARM_GIC_ICDICFR         0xC00 // Interrupt Configuration Registers

+

+#define ARM_GIC_ICDPPISR        0xD00 // PPI Status register

+

+// just one of these

+#define ARM_GIC_ICDSGIR         0xF00 // Software Generated Interrupt Register

+

+// GICv3 specific registers

+#define ARM_GICD_IROUTER        0x6100 // Interrupt Routing Registers

+

+// the Affinity Routing Enable (ARE) bit in GICD_CTLR

+#define ARM_GIC_ICDDCR_ARE      (1 << 4)

+

+//

+// GIC Redistributor

+//

+

+#define ARM_GICR_CTLR_FRAME_SIZE    SIZE_64KB

+#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB

+

+// GIC Redistributor Control frame

+#define ARM_GICR_TYPER          0x0008  // Redistributor Type Register

+

+// GIC SGI & PPI Redistributor frame

+#define ARM_GICR_ISENABLER      0x0100  // Interrupt Set-Enable Registers

+#define ARM_GICR_ICENABLER      0x0180  // Interrupt Clear-Enable Registers

+

+//

+// GIC Cpu interface

+//

+#define ARM_GIC_ICCICR          0x00  // CPU Interface Control Register

+#define ARM_GIC_ICCPMR          0x04  // Interrupt Priority Mask Register

+#define ARM_GIC_ICCBPR          0x08  // Binary Point Register

+#define ARM_GIC_ICCIAR          0x0C  // Interrupt Acknowledge Register

+#define ARM_GIC_ICCEIOR         0x10  // End Of Interrupt Register

+#define ARM_GIC_ICCRPR          0x14  // Running Priority Register

+#define ARM_GIC_ICCPIR          0x18  // Highest Pending Interrupt Register

+#define ARM_GIC_ICCABPR         0x1C  // Aliased Binary Point Register

+#define ARM_GIC_ICCIIDR         0xFC  // Identification Register

+

+#define ARM_GIC_ICDSGIR_FILTER_TARGETLIST       0x0

+#define ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE     0x1

+#define ARM_GIC_ICDSGIR_FILTER_ITSELF           0x2

+

+// Bit-masks to configure the CPU Interface Control register

+#define ARM_GIC_ICCICR_ENABLE_SECURE            0x01

+#define ARM_GIC_ICCICR_ENABLE_NS                0x02

+#define ARM_GIC_ICCICR_ACK_CTL                  0x04

+#define ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ     0x08

+#define ARM_GIC_ICCICR_USE_SBPR                 0x10

+

+// Bit Mask for GICC_IIDR

+#define ARM_GIC_ICCIIDR_GET_PRODUCT_ID(IccIidr)   (((IccIidr) >> 20) & 0xFFF)

+#define ARM_GIC_ICCIIDR_GET_ARCH_VERSION(IccIidr) (((IccIidr) >> 16) & 0xF)

+#define ARM_GIC_ICCIIDR_GET_REVISION(IccIidr)     (((IccIidr) >> 12) & 0xF)

+#define ARM_GIC_ICCIIDR_GET_IMPLEMENTER(IccIidr)  ((IccIidr) & 0xFFF)

+

+// Bit Mask for

+#define ARM_GIC_ICCIAR_ACKINTID                 0x3FF

+

+ARM_GIC_ARCH_REVISION

+EFIAPI

+ArmGicGetSupportedArchRevision (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmGicGetInterfaceIdentification (

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+//

+// GIC Secure interfaces

+//

+VOID

+EFIAPI

+ArmGicSetupNonSecure (

+  IN  UINTN         MpId,

+  IN  INTN          GicDistributorBase,

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+VOID

+EFIAPI

+ArmGicSetSecureInterrupts (

+  IN  UINTN         GicDistributorBase,

+  IN  UINTN*        GicSecureInterruptMask,

+  IN  UINTN         GicSecureInterruptMaskSize

+  );

+

+VOID

+EFIAPI

+ArmGicEnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+VOID

+EFIAPI

+ArmGicDisableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  );

+

+VOID

+EFIAPI

+ArmGicEnableDistributor (

+  IN  INTN          GicDistributorBase

+  );

+

+VOID

+EFIAPI

+ArmGicDisableDistributor (

+  IN  INTN          GicDistributorBase

+  );

+

+UINTN

+EFIAPI

+ArmGicGetMaxNumInterrupts (

+  IN  INTN          GicDistributorBase

+  );

+

+VOID

+EFIAPI

+ArmGicSendSgiTo (

+  IN  INTN          GicDistributorBase,

+  IN  INTN          TargetListFilter,

+  IN  INTN          CPUTargetList,

+  IN  INTN          SgiId

+  );

+

+/*

+ * Acknowledge and return the value of the Interrupt Acknowledge Register

+ *

+ * InterruptId is returned separately from the register value because in

+ * the GICv2 the register value contains the CpuId and InterruptId while

+ * in the GICv3 the register value is only the InterruptId.

+ *

+ * @param GicInterruptInterfaceBase   Base Address of the GIC CPU Interface

+ * @param InterruptId                 InterruptId read from the Interrupt Acknowledge Register

+ *

+ * @retval value returned by the Interrupt Acknowledge Register

+ *

+ */

+UINTN

+EFIAPI

+ArmGicAcknowledgeInterrupt (

+  IN  UINTN          GicInterruptInterfaceBase,

+  OUT UINTN          *InterruptId

+  );

+

+VOID

+EFIAPI

+ArmGicEndOfInterrupt (

+  IN  UINTN                 GicInterruptInterfaceBase,

+  IN UINTN                  Source

+  );

+

+UINTN

+EFIAPI

+ArmGicSetPriorityMask (

+  IN  INTN          GicInterruptInterfaceBase,

+  IN  INTN          PriorityMask

+  );

+

+VOID

+EFIAPI

+ArmGicEnableInterrupt (

+  IN UINTN                  GicDistributorBase,

+  IN UINTN                  GicRedistributorBase,

+  IN UINTN                  Source

+  );

+

+VOID

+EFIAPI

+ArmGicDisableInterrupt (

+  IN UINTN                  GicDistributorBase,

+  IN UINTN                  GicRedistributorBase,

+  IN UINTN                  Source

+  );

+

+BOOLEAN

+EFIAPI

+ArmGicIsInterruptEnabled (

+  IN UINTN                  GicDistributorBase,

+  IN UINTN                  GicRedistributorBase,

+  IN UINTN                  Source

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmHvcLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmHvcLib.h
new file mode 100644
index 0000000..4e9d1c4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmHvcLib.h
@@ -0,0 +1,46 @@
+/** @file

+*

+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+*

+*  This program and the accompanying materials

+*  are licensed and made available under the terms and conditions of the BSD License

+*  which accompanies this distribution.  The full text of the license may be found at

+*  http://opensource.org/licenses/bsd-license.php

+*

+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+*

+**/

+

+#ifndef __ARM_HVC_LIB__

+#define __ARM_HVC_LIB__

+

+/**

+ * The size of the HVC arguments are different between AArch64 and AArch32.

+ * The native size is used for the arguments.

+ */

+typedef struct {

+  UINTN  Arg0;

+  UINTN  Arg1;

+  UINTN  Arg2;

+  UINTN  Arg3;

+  UINTN  Arg4;

+  UINTN  Arg5;

+  UINTN  Arg6;

+  UINTN  Arg7;

+} ARM_HVC_ARGS;

+

+/**

+  Trigger an HVC call

+

+  HVC calls can take up to 8 arguments and return up to 4 return values.

+  Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used

+  for both input and output values.

+

+**/

+VOID

+ArmCallHvc (

+  IN OUT ARM_HVC_ARGS *Args

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmLib.h
new file mode 100644
index 0000000..9effb3e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmLib.h
@@ -0,0 +1,668 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __ARM_LIB__

+#define __ARM_LIB__

+

+#include <Uefi/UefiBaseType.h>

+

+#ifdef MDE_CPU_ARM

+  #ifdef ARM_CPU_ARMv6

+    #include <Chipset/ARM1176JZ-S.h>

+  #else

+    #include <Chipset/ArmV7.h>

+  #endif

+#elif defined(MDE_CPU_AARCH64)

+  #include <Chipset/AArch64.h>

+#else

+ #error "Unknown chipset."

+#endif

+

+typedef enum {

+  ARM_CACHE_TYPE_WRITE_BACK,

+  ARM_CACHE_TYPE_UNKNOWN

+} ARM_CACHE_TYPE;

+

+typedef enum {

+  ARM_CACHE_ARCHITECTURE_UNIFIED,

+  ARM_CACHE_ARCHITECTURE_SEPARATE,

+  ARM_CACHE_ARCHITECTURE_UNKNOWN

+} ARM_CACHE_ARCHITECTURE;

+

+typedef struct {

+  ARM_CACHE_TYPE          Type;

+  ARM_CACHE_ARCHITECTURE  Architecture;

+  BOOLEAN                 DataCachePresent;

+  UINTN                   DataCacheSize;

+  UINTN                   DataCacheAssociativity;

+  UINTN                   DataCacheLineLength;

+  BOOLEAN                 InstructionCachePresent;

+  UINTN                   InstructionCacheSize;

+  UINTN                   InstructionCacheAssociativity;

+  UINTN                   InstructionCacheLineLength;

+} ARM_CACHE_INFO;

+

+/**

+ * The UEFI firmware must not use the ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_* attributes.

+ *

+ * The Non Secure memory attribute (ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_*) should only

+ * be used in Secure World to distinguished Secure to Non-Secure memory.

+ */

+typedef enum {

+  ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED = 0,

+  ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED,

+  ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,

+  ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK,

+  ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH,

+  ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH,

+  ARM_MEMORY_REGION_ATTRIBUTE_DEVICE,

+  ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE

+} ARM_MEMORY_REGION_ATTRIBUTES;

+

+#define IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(attr) ((UINT32)(attr) & 1)

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS          PhysicalBase;

+  EFI_VIRTUAL_ADDRESS           VirtualBase;

+  UINT64                        Length;

+  ARM_MEMORY_REGION_ATTRIBUTES  Attributes;

+} ARM_MEMORY_REGION_DESCRIPTOR;

+

+typedef VOID (*CACHE_OPERATION)(VOID);

+typedef VOID (*LINE_OPERATION)(UINTN);

+

+//

+// ARM Processor Mode

+//

+typedef enum {

+  ARM_PROCESSOR_MODE_USER       = 0x10,

+  ARM_PROCESSOR_MODE_FIQ        = 0x11,

+  ARM_PROCESSOR_MODE_IRQ        = 0x12,

+  ARM_PROCESSOR_MODE_SUPERVISOR = 0x13,

+  ARM_PROCESSOR_MODE_ABORT      = 0x17,

+  ARM_PROCESSOR_MODE_HYP        = 0x1A,

+  ARM_PROCESSOR_MODE_UNDEFINED  = 0x1B,

+  ARM_PROCESSOR_MODE_SYSTEM     = 0x1F,

+  ARM_PROCESSOR_MODE_MASK       = 0x1F

+} ARM_PROCESSOR_MODE;

+

+//

+// ARM Cpu IDs

+//

+#define ARM_CPU_IMPLEMENTER_MASK          (0xFFU << 24)

+#define ARM_CPU_IMPLEMENTER_ARMLTD        (0x41U << 24)

+#define ARM_CPU_IMPLEMENTER_DEC           (0x44U << 24)

+#define ARM_CPU_IMPLEMENTER_MOT           (0x4DU << 24)

+#define ARM_CPU_IMPLEMENTER_QUALCOMM      (0x51U << 24)

+#define ARM_CPU_IMPLEMENTER_MARVELL       (0x56U << 24)

+

+#define ARM_CPU_PRIMARY_PART_MASK         (0xFFF << 4)

+#define ARM_CPU_PRIMARY_PART_CORTEXA5     (0xC05 << 4)

+#define ARM_CPU_PRIMARY_PART_CORTEXA7     (0xC07 << 4)

+#define ARM_CPU_PRIMARY_PART_CORTEXA8     (0xC08 << 4)

+#define ARM_CPU_PRIMARY_PART_CORTEXA9     (0xC09 << 4)

+#define ARM_CPU_PRIMARY_PART_CORTEXA15    (0xC0F << 4)

+

+//

+// ARM MP Core IDs

+//

+#define ARM_CORE_AFF0         0xFF

+#define ARM_CORE_AFF1         (0xFF << 8)

+#define ARM_CORE_AFF2         (0xFF << 16)

+#define ARM_CORE_AFF3         (0xFFULL << 32)

+

+#define ARM_CORE_MASK         ARM_CORE_AFF0

+#define ARM_CLUSTER_MASK      ARM_CORE_AFF1

+#define GET_CORE_ID(MpId)     ((MpId) & ARM_CORE_MASK)

+#define GET_CLUSTER_ID(MpId)  (((MpId) & ARM_CLUSTER_MASK) >> 8)

+#define GET_MPID(ClusterId, CoreId)   (((ClusterId) << 8) | (CoreId))

+#define PRIMARY_CORE_ID       (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK)

+

+ARM_CACHE_TYPE

+EFIAPI

+ArmCacheType (

+  VOID

+  );

+

+ARM_CACHE_ARCHITECTURE

+EFIAPI

+ArmCacheArchitecture (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmCacheInformation (

+  OUT ARM_CACHE_INFO  *CacheInfo

+  );

+

+BOOLEAN

+EFIAPI

+ArmDataCachePresent (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDataCacheSize (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDataCacheAssociativity (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDataCacheLineLength (

+  VOID

+  );

+

+BOOLEAN

+EFIAPI

+ArmInstructionCachePresent (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmInstructionCacheSize (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmInstructionCacheAssociativity (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmInstructionCacheLineLength (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmIsArchTimerImplemented (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadIdPfr0 (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadIdPfr1 (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmCacheInfo (

+  VOID

+  );

+

+BOOLEAN

+EFIAPI

+ArmIsMpCore (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmInvalidateDataCache (

+  VOID

+  );

+

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmCleanDataCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmCleanDataCacheToPoU (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmInvalidateInstructionCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmInvalidateDataCacheEntryByMVA (

+  IN  UINTN   Address

+  );

+

+VOID

+EFIAPI

+ArmCleanDataCacheEntryByMVA (

+  IN  UINTN   Address

+  );

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCacheEntryByMVA (

+  IN  UINTN   Address

+  );

+

+VOID

+EFIAPI

+ArmInvalidateDataCacheEntryBySetWay (

+  IN  UINTN  SetWayFormat

+  );

+

+VOID

+EFIAPI

+ArmCleanDataCacheEntryBySetWay (

+  IN  UINTN  SetWayFormat

+  );

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCacheEntryBySetWay (

+  IN  UINTN   SetWayFormat

+  );

+

+VOID

+EFIAPI

+ArmEnableDataCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDisableDataCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableInstructionCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDisableInstructionCache (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableMmu (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDisableMmu (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableCachesAndMmu (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDisableCachesAndMmu (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableInterrupts (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDisableInterrupts (

+  VOID

+  );

+

+BOOLEAN

+EFIAPI

+ArmGetInterruptState (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableAsynchronousAbort (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDisableAsynchronousAbort (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableIrq (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDisableIrq (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableFiq (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmDisableFiq (

+  VOID

+  );

+

+BOOLEAN

+EFIAPI

+ArmGetFiqState (

+  VOID

+  );

+

+/**

+ * Invalidate Data and Instruction TLBs

+ */

+VOID

+EFIAPI

+ArmInvalidateTlb (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmUpdateTranslationTableEntry (

+  IN  VOID     *TranslationTableEntry,

+  IN  VOID     *Mva

+  );

+

+VOID

+EFIAPI

+ArmSetDomainAccessControl (

+  IN  UINT32  Domain

+  );

+

+VOID

+EFIAPI

+ArmSetTTBR0 (

+  IN  VOID  *TranslationTableBase

+  );

+

+VOID *

+EFIAPI

+ArmGetTTBR0BaseAddress (

+  VOID

+  );

+

+RETURN_STATUS

+EFIAPI

+ArmConfigureMmu (

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,

+  OUT VOID                         **TranslationTableBase OPTIONAL,

+  OUT UINTN                         *TranslationTableSize  OPTIONAL

+  );

+

+BOOLEAN

+EFIAPI

+ArmMmuEnabled (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmEnableBranchPrediction (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDisableBranchPrediction (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmSetLowVectors (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmSetHighVectors (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDrainWriteBuffer (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDataMemoryBarrier (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmDataSyncronizationBarrier (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmInstructionSynchronizationBarrier (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteVBar (

+  IN  UINTN   VectorBase

+  );

+

+UINTN

+EFIAPI

+ArmReadVBar (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteAuxCr (

+  IN  UINT32    Bit

+  );

+

+UINT32

+EFIAPI

+ArmReadAuxCr (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmSetAuxCrBit (

+  IN  UINT32    Bits

+  );

+

+VOID

+EFIAPI

+ArmUnsetAuxCrBit (

+  IN  UINT32    Bits

+  );

+

+VOID

+EFIAPI

+ArmCallSEV (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmCallWFE (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmCallWFI (

+

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadMpidr (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadMidr (

+  VOID

+  );

+

+UINT32

+EFIAPI

+ArmReadCpacr (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCpacr (

+  IN  UINT32   Access

+  );

+

+VOID

+EFIAPI

+ArmEnableVFP (

+  VOID

+  );

+

+/**

+  Get the Secure Configuration Register value

+

+  @return   Value read from the Secure Configuration Register

+

+**/

+UINT32

+EFIAPI

+ArmReadScr (

+  VOID

+  );

+

+/**

+  Set the Secure Configuration Register

+

+  @param Value   Value to write to the Secure Configuration Register

+

+**/

+VOID

+EFIAPI

+ArmWriteScr (

+  IN  UINT32   Value

+  );

+

+UINT32

+EFIAPI

+ArmReadMVBar (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteMVBar (

+  IN  UINT32   VectorMonitorBase

+  );

+

+UINT32

+EFIAPI

+ArmReadSctlr (

+  VOID

+  );

+

+UINTN

+EFIAPI

+ArmReadHVBar (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteHVBar (

+  IN  UINTN   HypModeVectorBase

+  );

+

+

+//

+// Helper functions for accessing CPU ACTLR

+//

+

+UINTN

+EFIAPI

+ArmReadCpuActlr (

+  VOID

+  );

+

+VOID

+EFIAPI

+ArmWriteCpuActlr (

+  IN  UINTN Val

+  );

+

+VOID

+EFIAPI

+ArmSetCpuActlrBit (

+  IN  UINTN    Bits

+  );

+

+VOID

+EFIAPI

+ArmUnsetCpuActlrBit (

+  IN  UINTN    Bits

+  );

+

+#endif // __ARM_LIB__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmSmcLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmSmcLib.h
new file mode 100644
index 0000000..168e3bb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmSmcLib.h
@@ -0,0 +1,46 @@
+/** @file

+*

+*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+*

+*  This program and the accompanying materials

+*  are licensed and made available under the terms and conditions of the BSD License

+*  which accompanies this distribution.  The full text of the license may be found at

+*  http://opensource.org/licenses/bsd-license.php

+*

+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+*

+**/

+

+#ifndef __ARM_SMC_LIB__

+#define __ARM_SMC_LIB__

+

+/**

+ * The size of the SMC arguments are different between AArch64 and AArch32.

+ * The native size is used for the arguments.

+ */

+typedef struct {

+  UINTN  Arg0;

+  UINTN  Arg1;

+  UINTN  Arg2;

+  UINTN  Arg3;

+  UINTN  Arg4;

+  UINTN  Arg5;

+  UINTN  Arg6;

+  UINTN  Arg7;

+} ARM_SMC_ARGS;

+

+/**

+  Trigger an SMC call

+

+  SMC calls can take up to 7 arguments and return up to 4 return values.

+  Therefore, the 4 first fields in the ARM_SMC_ARGS structure are used

+  for both input and output values.

+

+**/

+VOID

+ArmCallSmc (

+  IN OUT ARM_SMC_ARGS *Args

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/BdsLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/BdsLib.h
new file mode 100644
index 0000000..9fa6870
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/BdsLib.h
@@ -0,0 +1,225 @@
+/** @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.

+*

+**/

+

+#ifndef __BDS_ENTRY_H__

+#define __BDS_ENTRY_H__

+

+typedef UINT8* EFI_LOAD_OPTION;

+

+/**

+  This is defined by the UEFI specs, don't change it

+**/

+typedef struct {

+  UINT16                      LoadOptionIndex;

+  EFI_LOAD_OPTION             LoadOption;

+  UINTN                       LoadOptionSize;

+

+  UINT32                      Attributes;

+  UINT16                      FilePathListLength;

+  CHAR16                      *Description;

+  EFI_DEVICE_PATH_PROTOCOL    *FilePathList;

+

+  VOID*                       OptionalData;

+  UINTN                       OptionalDataSize;

+} BDS_LOAD_OPTION;

+

+/**

+  Connect a Device Path and return the handle of the driver that support this DevicePath

+

+  @param  DevicePath            Device Path of the File to connect

+  @param  Handle                Handle of the driver that support this DevicePath

+  @param  RemainingDevicePath   Remaining DevicePath nodes that do not match the driver DevicePath

+

+  @retval EFI_SUCCESS           A driver that matches the Device Path has been found

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL

+

+**/

+EFI_STATUS

+BdsConnectDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,

+  OUT EFI_HANDLE                *Handle,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath

+  );

+

+/**

+  Connect all DXE drivers

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_OUT_OF_RESOURCES  There is not resource pool memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsConnectAllDrivers (

+  VOID

+  );

+

+/**

+  Return the value of a global variable defined by its VariableName.

+  The variable must be defined with the VendorGuid gEfiGlobalVariableGuid.

+

+  @param  VariableName          A Null-terminated string that is the name of the vendor's

+                                variable.

+  @param  DefaultValue          Value returned by the function if the variable does not exist

+  @param  DataSize              On input, the size in bytes of the return Data buffer.

+                                On output the size of data returned in Data.

+  @param  Value                 Value read from the UEFI Variable or copy of the default value

+                                if the UEFI Variable does not exist

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_OUT_OF_RESOURCES  There is not resource pool memory to store the matching results.

+

+**/

+EFI_STATUS

+GetGlobalEnvironmentVariable (

+  IN     CONST CHAR16*   VariableName,

+  IN     VOID*           DefaultValue,

+  IN OUT UINTN*          Size,

+  OUT    VOID**          Value

+  );

+

+/**

+  Return the value of the variable defined by its VariableName and VendorGuid

+

+  @param  VariableName          A Null-terminated string that is the name of the vendor's

+                                variable.

+  @param  VendorGuid            A unique identifier for the vendor.

+  @param  DefaultValue          Value returned by the function if the variable does not exist

+  @param  DataSize              On input, the size in bytes of the return Data buffer.

+                                On output the size of data returned in Data.

+  @param  Value                 Value read from the UEFI Variable or copy of the default value

+                                if the UEFI Variable does not exist

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_OUT_OF_RESOURCES  There is not resource pool memory to store the matching results.

+

+**/

+EFI_STATUS

+GetEnvironmentVariable (

+  IN     CONST CHAR16*   VariableName,

+  IN     EFI_GUID*       VendorGuid,

+  IN     VOID*           DefaultValue,

+  IN OUT UINTN*          Size,

+  OUT    VOID**          Value

+  );

+

+EFI_STATUS

+BootOptionFromLoadOptionIndex (

+  IN  UINT16            LoadOptionIndex,

+  OUT BDS_LOAD_OPTION** BdsLoadOption

+  );

+

+EFI_STATUS

+BootOptionFromLoadOptionVariable (

+  IN  CHAR16*           BootVariableName,

+  OUT BDS_LOAD_OPTION** BdsLoadOption

+  );

+

+EFI_STATUS

+BootOptionToLoadOptionVariable (

+  IN BDS_LOAD_OPTION*   BdsLoadOption

+  );

+

+UINT16

+BootOptionAllocateBootIndex (

+  VOID

+  );

+

+/**

+  Start a Linux kernel from a Device Path

+

+  @param  LinuxKernel           Device Path to the Linux Kernel

+  @param  Parameters            Linux kernel arguments

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsBootLinuxAtag (

+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,

+  IN  CONST CHAR8*              Arguments

+  );

+

+/**

+  Start a Linux kernel from a Device Path

+

+  @param  LinuxKernel           Device Path to the Linux Kernel

+  @param  Parameters            Linux kernel arguments

+  @param  Fdt                   Device Path to the Flat Device Tree

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsBootLinuxFdt (

+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,

+  IN  CONST CHAR8*              Arguments,

+  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath

+  );

+

+/**

+  Start an EFI Application from a Device Path

+

+  @param  ParentImageHandle     Handle of the calling image

+  @param  DevicePath            Location of the EFI Application

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsStartEfiApplication (

+  IN EFI_HANDLE                  ParentImageHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL    *DevicePath,

+  IN UINTN                       LoadOptionsSize,

+  IN VOID*                       LoadOptions

+  );

+

+/**

+  Start an EFI Application from any Firmware Volume

+

+  @param  EfiApp                EFI Application Name

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsLoadApplication (

+  IN EFI_HANDLE                  ParentImageHandle,

+  IN CHAR16*                     EfiApp,

+  IN UINTN                       LoadOptionsSize,

+  IN VOID*                       LoadOptions

+  );

+

+EFI_STATUS

+BdsLoadImage (

+  IN     EFI_DEVICE_PATH       *DevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS* Image,

+  OUT    UINTN                 *FileSize

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h
new file mode 100644
index 0000000..5c7d7e2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h
@@ -0,0 +1,31 @@
+/** @file

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __DEFAULT_EXCEPTION_HANDLER_LIB_H__

+#define __DEFAULT_EXCEPTION_HANDLER_LIB_H__

+

+/**

+  This is the default action to take on an unexpected exception

+

+  @param  ExceptionType    Type of the exception

+  @param  SystemContext    Register state at the time of the Exception

+

+**/

+VOID

+DefaultExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/SemihostLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/SemihostLib.h
new file mode 100644
index 0000000..4a91593
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/SemihostLib.h
@@ -0,0 +1,138 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Portions 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 __SEMIHOSTING_H__

+#define __SEMIHOSTING_H__

+

+/*

+ *

+ *  Please refer to ARM RVDS 3.0 Compiler and Libraries Guide for more information

+ *  about the semihosting interface.

+ *

+ */

+

+#define SEMIHOST_FILE_MODE_READ     (0 << 2)

+#define SEMIHOST_FILE_MODE_WRITE    (1 << 2)

+#define SEMIHOST_FILE_MODE_APPEND   (2 << 2)

+#define SEMIHOST_FILE_MODE_UPDATE   (1 << 1)

+#define SEMIHOST_FILE_MODE_BINARY   (1 << 0)

+#define SEMIHOST_FILE_MODE_ASCII    (0 << 0)

+

+BOOLEAN

+SemihostConnectionSupported (

+  VOID

+  );

+

+RETURN_STATUS

+SemihostFileOpen (

+  IN  CHAR8  *FileName,

+  IN  UINT32 Mode,

+  OUT UINTN  *FileHandle

+  );

+

+RETURN_STATUS

+SemihostFileSeek (

+  IN UINTN  FileHandle,

+  IN UINTN  Offset

+  );

+

+RETURN_STATUS

+SemihostFileRead (

+  IN     UINTN  FileHandle,

+  IN OUT UINTN  *Length,

+  OUT    VOID   *Buffer

+  );

+

+RETURN_STATUS

+SemihostFileWrite (

+  IN     UINTN  FileHandle,

+  IN OUT UINTN  *Length,

+  IN     VOID   *Buffer

+  );

+

+RETURN_STATUS

+SemihostFileClose (

+  IN UINTN  FileHandle

+  );

+

+RETURN_STATUS

+SemihostFileLength (

+  IN  UINTN  FileHandle,

+  OUT UINTN  *Length

+  );

+

+/**

+  Get a temporary name for a file from the host running the debug agent.

+

+  @param[out]  Buffer      Pointer to the buffer where the temporary name has to

+                           be stored

+  @param[in]   Identifier  File name identifier (integer in the range 0 to 255)

+  @param[in]   Length      Length of the buffer to store the temporary name

+

+  @retval  RETURN_SUCCESS            Temporary name returned

+  @retval  RETURN_INVALID_PARAMETER  Invalid buffer address

+  @retval  RETURN_ABORTED            Temporary name not returned

+

+**/

+RETURN_STATUS

+SemihostFileTmpName(

+  OUT  VOID   *Buffer,

+  IN   UINT8  Identifier,

+  IN   UINTN  Length

+  );

+

+RETURN_STATUS

+SemihostFileRemove (

+  IN CHAR8 *FileName

+  );

+

+/**

+  Rename a specified file.

+

+  @param[in]  FileName     Name of the file to rename.

+  @param[in]  NewFileName  The new name of the file.

+

+  @retval  RETURN_SUCCESS            File Renamed

+  @retval  RETURN_INVALID_PARAMETER  Either the current or the new name is not specified

+  @retval  RETURN_ABORTED            Rename failed

+

+**/

+RETURN_STATUS

+SemihostFileRename(

+  IN  CHAR8  *FileName,

+  IN  CHAR8  *NewFileName

+  );

+

+CHAR8

+SemihostReadCharacter (

+  VOID

+  );

+

+VOID

+SemihostWriteCharacter (

+  IN CHAR8 Character

+  );

+

+VOID

+SemihostWriteString (

+  IN CHAR8 *String

+  );

+

+UINT32

+SemihostSystem (

+  IN CHAR8 *CommandLine

+  );

+

+#endif // __SEMIHOSTING_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h
new file mode 100644
index 0000000..a49d8d3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h
@@ -0,0 +1,665 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __UNCACHED_MEMORY_ALLOCATION_LIB_H__

+#define __UNCACHED_MEMORY_ALLOCATION_LIB_H__

+

+/**

+  Converts a cached or uncached address to a physical address suitable for use in SoC registers.

+

+  @param  VirtualAddress                 The pointer to convert.

+

+  @return The physical address of the supplied virtual pointer.

+

+**/

+EFI_PHYSICAL_ADDRESS

+ConvertToPhysicalAddress (

+  IN VOID *VirtualAddress

+  );

+

+/**

+  Converts a cached or uncached address to a cached address.

+

+  @param  Address                 The pointer to convert.

+

+  @return The address of the cached memory location corresponding to the input address.

+

+**/

+VOID *

+ConvertToCachedAddress (

+  IN VOID *Address

+  );

+

+/**

+  Converts a cached or uncached address to an uncached address.

+

+  @param  Address                 The pointer to convert.

+

+  @return The address of the uncached memory location corresponding to the input address.

+

+**/

+VOID *

+ConvertToUncachedAddress (

+  IN VOID *Address

+  );

+

+/**

+  Allocates one or more 4KB pages of type EfiBootServicesData.

+

+  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the

+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL

+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is

+  returned.

+

+  @param  Pages                 The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocatePages (

+  IN UINTN  Pages

+  );

+

+/**

+  Allocates one or more 4KB pages of type EfiRuntimeServicesData.

+

+  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the

+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL

+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is

+  returned.

+

+  @param  Pages                 The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateRuntimePages (

+  IN UINTN  Pages

+  );

+

+/**

+  Allocates one or more 4KB pages of type EfiReservedMemoryType.

+

+  Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the

+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL

+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is

+  returned.

+

+  @param  Pages                 The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateReservedPages (

+  IN UINTN  Pages

+  );

+

+/**

+  Frees one or more 4KB pages that were previously allocated with one of the page allocation

+  functions in the Memory Allocation Library.

+

+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer

+  must have been allocated on a previous call to the page allocation services of the Memory

+  Allocation Library.

+  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,

+  then ASSERT().

+  If Pages is zero, then ASSERT().

+

+  @param  Buffer                Pointer to the buffer of pages to free.

+  @param  Pages                 The number of 4 KB pages to free.

+

+**/

+VOID

+EFIAPI

+UncachedFreePages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  );

+

+/**

+  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.

+

+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is

+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the

+  request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  Pages                 The number of 4 KB pages to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.

+

+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is

+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the

+  request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  Pages                 The number of 4 KB pages to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimePages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.

+

+  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is

+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the

+  request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  Pages                 The number of 4 KB pages to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedPages (

+  IN UINTN  Pages,

+  IN UINTN  Alignment

+  );

+

+/**

+  Frees one or more 4KB pages that were previously allocated with one of the aligned page

+  allocation functions in the Memory Allocation Library.

+

+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer

+  must have been allocated on a previous call to the aligned page allocation services of the Memory

+  Allocation Library.

+  If Buffer was not allocated with an aligned page allocation function in the Memory Allocation

+  Library, then ASSERT().

+  If Pages is zero, then ASSERT().

+

+  @param  Buffer                Pointer to the buffer of pages to free.

+  @param  Pages                 The number of 4 KB pages to free.

+

+**/

+VOID

+EFIAPI

+UncachedFreeAlignedPages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  );

+

+/**

+  Allocates a buffer of type EfiBootServicesData.

+

+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a

+  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is

+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+  @param  AllocationSize        The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocatePool (

+  IN UINTN  AllocationSize

+  );

+

+/**

+  Allocates a buffer of type EfiRuntimeServicesData.

+

+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns

+  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is

+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+  @param  AllocationSize        The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateRuntimePool (

+  IN UINTN  AllocationSize

+  );

+

+/**

+  Allocates a buffer of type EfieservedMemoryType.

+

+  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns

+  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is

+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.

+

+  @param  AllocationSize        The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateReservedPool (

+  IN UINTN  AllocationSize

+  );

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData.

+

+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the

+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a

+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the

+  request, then NULL is returned.

+

+  @param  AllocationSize        The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateZeroPool (

+  IN UINTN  AllocationSize

+  );

+

+/**

+  Allocates and zeros a buffer of type EfiRuntimeServicesData.

+

+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the

+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a

+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the

+  request, then NULL is returned.

+

+  @param  AllocationSize        The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateRuntimeZeroPool (

+  IN UINTN  AllocationSize

+  );

+

+/**

+  Allocates and zeros a buffer of type EfiReservedMemoryType.

+

+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the

+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a

+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the

+  request, then NULL is returned.

+

+  @param  AllocationSize        The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateReservedZeroPool (

+  IN UINTN  AllocationSize

+  );

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData.

+

+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies

+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the

+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there

+  is not enough memory remaining to satisfy the request, then NULL is returned.

+  If Buffer is NULL, then ASSERT().

+  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate and zero.

+  @param  Buffer                The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  );

+

+/**

+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.

+

+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies

+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the

+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there

+  is not enough memory remaining to satisfy the request, then NULL is returned.

+  If Buffer is NULL, then ASSERT().

+  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate and zero.

+  @param  Buffer                The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  );

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.

+

+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies

+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the

+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there

+  is not enough memory remaining to satisfy the request, then NULL is returned.

+  If Buffer is NULL, then ASSERT().

+  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate and zero.

+  @param  Buffer                The buffer to copy to the allocated buffer.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  );

+

+/**

+  Frees a buffer that was previously allocated with one of the pool allocation functions in the

+  Memory Allocation Library.

+

+  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the

+  pool allocation services of the Memory Allocation Library.

+  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,

+  then ASSERT().

+

+  @param  Buffer                Pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+UncachedFreePool (

+  IN VOID   *Buffer

+  );

+

+/**

+  Allocates a buffer of type EfiBootServicesData at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,

+  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified

+  alignment remaining to satisfy the request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,

+  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified

+  alignment remaining to satisfy the request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimePool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates a buffer of type EfieservedMemoryType at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,

+  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified

+  alignment remaining to satisfy the request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an

+  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the

+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there

+  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is

+  returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an

+  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the

+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there

+  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is

+  returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimeZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  );

+

+/**

+  Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an

+  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the

+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there

+  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is

+  returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  );

+

+/**

+  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,

+  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified

+  alignment remaining to satisfy the request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Buffer                The buffer to copy to the allocated buffer.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  );

+

+/**

+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,

+  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified

+  alignment remaining to satisfy the request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Buffer                The buffer to copy to the allocated buffer.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  );

+

+/**

+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.

+

+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an

+  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,

+  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified

+  alignment remaining to satisfy the request, then NULL is returned.

+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().

+

+  @param  AllocationSize        The number of bytes to allocate.

+  @param  Buffer                The buffer to copy to the allocated buffer.

+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.

+                                If Alignment is zero, then byte alignment is used.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  );

+

+/**

+  Frees a buffer that was previously allocated with one of the aligned pool allocation functions

+  in the Memory Allocation Library.

+

+  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the

+  aligned pool allocation services of the Memory Allocation Library.

+  If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation

+  Library, then ASSERT().

+

+  @param  Buffer                Pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+UncachedFreeAlignedPool (

+  IN VOID   *Buffer

+  );

+

+VOID

+EFIAPI

+UncachedSafeFreePool (

+  IN VOID   *Buffer

+  );

+

+#endif // __UNCACHED_MEMORY_ALLOCATION_LIB_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Ppi/ArmMpCoreInfo.h b/uefi/linaro-edk2/ArmPkg/Include/Ppi/ArmMpCoreInfo.h
new file mode 100644
index 0000000..fdacd81
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Ppi/ArmMpCoreInfo.h
@@ -0,0 +1,58 @@
+/** @file

+*

+*  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_MP_CORE_INFO_PPI_H__

+#define __ARM_MP_CORE_INFO_PPI_H__

+

+#include <Guid/ArmMpCoreInfo.h>

+

+#define ARM_MP_CORE_INFO_PPI_GUID  \

+  { 0x6847cc74, 0xe9ec, 0x4f8f, {0xa2, 0x9d, 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc} }

+

+/**

+  This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into

+  permanent memory.

+

+  @param PeiServices            Pointer to the PEI Services Table.

+  @param TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the

+                                Temporary RAM contents.

+  @param PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the

+                                Temporary RAM contents.

+  @param CopySize               Amount of memory to migrate from temporary to permanent memory.

+

+  @retval EFI_SUCCESS           The data was successfully returned.

+  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when

+                                TemporaryMemoryBase > PermanentMemoryBase.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI * ARM_MP_CORE_INFO_GET) (

+  OUT UINTN                   *ArmCoreCount,

+  OUT ARM_CORE_INFO           **ArmCoreTable

+);

+

+///

+/// This service abstracts the ability to migrate contents of the platform early memory store.

+/// Note: The name EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI is different from the current PI 1.2 spec.

+///       This PPI was optional.

+///

+typedef struct {

+  ARM_MP_CORE_INFO_GET   GetMpCoreInfo;

+} ARM_MP_CORE_INFO_PPI;

+

+extern EFI_GUID gArmMpCoreInfoPpiGuid;

+extern EFI_GUID gArmMpCoreInfoGuid;

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Include/Protocol/VirtualUncachedPages.h b/uefi/linaro-edk2/ArmPkg/Include/Protocol/VirtualUncachedPages.h
new file mode 100644
index 0000000..0822184
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Protocol/VirtualUncachedPages.h
@@ -0,0 +1,60 @@
+/** @file

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __VIRTUAL_UNCACHED_PAGES_ROTOCOL_H__

+#define __VIRTUAL_UNCACHED_PAGES_ROTOCOL_H__

+

+//

+// Protocol GUID

+//

+#define VIRTUAL_UNCACHED_PAGES_PROTOCOL_GUID { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }

+

+

+

+//

+// Protocol interface structure

+//

+typedef struct _VIRTUAL_UNCACHED_PAGES_PROTOCOL  VIRTUAL_UNCACHED_PAGES_PROTOCOL;

+

+

+typedef

+EFI_STATUS

+(EFIAPI *CONVERT_PAGES_TO_UNCACHED_VIRTUAL_ADDRESS) (

+  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,

+  IN  EFI_PHYSICAL_ADDRESS              Address,

+  IN  UINTN                             Length,

+  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,

+  OUT UINT64                            *Attributes     OPTIONAL

+  );

+

+typedef

+EFI_STATUS

+(EFIAPI *FREE_CONVERTED_PAGES) (

+  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,

+  IN  EFI_PHYSICAL_ADDRESS              Address,

+  IN  UINTN                             Length,

+  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,

+  IN  UINT64                            Attributes

+  );

+

+

+

+struct _VIRTUAL_UNCACHED_PAGES_PROTOCOL {

+  CONVERT_PAGES_TO_UNCACHED_VIRTUAL_ADDRESS  ConvertPages;

+  FREE_CONVERTED_PAGES                       RevertPages;

+};

+

+extern EFI_GUID gVirtualUncachedPagesProtocolGuid;

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
new file mode 100644
index 0000000..a0e4f58
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
@@ -0,0 +1,231 @@
+/** @file

+  Generic ARM implementation of TimerLib.h

+

+  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.

+

+**/

+

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/TimerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/ArmGenericTimerCounterLib.h>

+

+#define TICKS_PER_MICRO_SEC     (PcdGet32 (PcdArmArchTimerFreqInHz)/1000000U)

+

+RETURN_STATUS

+EFIAPI

+TimerConstructor (

+  VOID

+  )

+{

+  //

+  // Check if the ARM Generic Timer Extension is implemented.

+  //

+  if (ArmIsArchTimerImplemented ()) {

+    UINTN TimerFreq;

+

+    //

+    // Check if Architectural Timer frequency is pre-determined by the platform

+    // (ie. nonzero).

+    //

+    if (PcdGet32 (PcdArmArchTimerFreqInHz) != 0) {

+      //

+      // Check if ticks/uS is not 0. The Architectural timer runs at constant

+      // frequency, irrespective of CPU frequency. According to General Timer

+      // Ref manual, lower bound of the frequency is in the range of 1-10MHz.

+      //

+      ASSERT (TICKS_PER_MICRO_SEC);

+

+#ifdef MDE_CPU_ARM

+      //

+      // Only set the frequency for ARMv7. We expect the secure firmware to

+      // have already done it.

+      // If the security extension is not implemented, set Timer Frequency

+      // here.

+      //

+      if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) {

+        ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));

+      }

+#endif

+    }

+

+    //

+    // Architectural Timer Frequency must be set in the Secure privileged

+    // mode (if secure extension is supported).

+    // If the reset value (0) is returned, just ASSERT.

+    //

+    TimerFreq = ArmGenericTimerGetTimerFreq ();

+    ASSERT (TimerFreq != 0);

+  } else {

+    DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence this library can not be used.\n"));

+    ASSERT (0);

+  }

+

+  return RETURN_SUCCESS;

+}

+

+

+/**

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return The value of MicroSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  UINT64 TimerTicks64;

+  UINT64 SystemCounterVal;

+  UINT64 (EFIAPI

+          *MultU64xN) (

+            IN UINT64 Multiplicand,

+            IN UINTN  Multiplier

+            );

+  UINTN TimerFreq;

+

+#ifdef MDE_CPU_ARM

+  MultU64xN = MultU64x32;

+#else

+  MultU64xN = MultU64x64;

+#endif

+

+  TimerFreq = PcdGet32 (PcdArmArchTimerFreqInHz);

+  if (TimerFreq == 0) {

+    TimerFreq = ArmGenericTimerGetTimerFreq ();

+  }

+

+  // Calculate counter ticks that can represent requested delay:

+  //  = MicroSeconds x TICKS_PER_MICRO_SEC

+  //  = MicroSeconds x Frequency.10^-6

+  TimerTicks64 = DivU64x32 (

+                   MultU64xN (

+                     MicroSeconds,

+                     TimerFreq

+                     ),

+                   1000000U

+                   );

+

+  // Read System Counter value

+  SystemCounterVal = ArmGenericTimerGetSystemCount ();

+

+  TimerTicks64 += SystemCounterVal;

+

+  // Wait until delay count is expired.

+  while (SystemCounterVal < TimerTicks64) {

+    SystemCounterVal = ArmGenericTimerGetSystemCount ();

+  }

+

+  return MicroSeconds;

+}

+

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  When the timer frequency is 1MHz, each tick corresponds to 1 microsecond.

+  Therefore, the nanosecond delay will be rounded up to the nearest 1 microsecond.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return The value of NanoSeconds inputed.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN  UINTN NanoSeconds

+  )

+{

+  UINTN  MicroSeconds;

+

+  // Round up to 1us Tick Number

+  MicroSeconds = NanoSeconds / 1000;

+  MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;

+

+  MicroSecondDelay (MicroSeconds);

+

+  return NanoSeconds;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  The counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  // Just return the value of system count

+  return ArmGenericTimerGetSystemCount ();

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  OUT      UINT64                    *StartValue,  OPTIONAL

+  OUT      UINT64                    *EndValue     OPTIONAL

+  )

+{

+  if (StartValue != NULL) {

+    // Timer starts with the reload value

+    *StartValue = (UINT64)0ULL ;

+  }

+

+  if (EndValue != NULL) {

+    // Timer counts down to 0x0

+    *EndValue = 0xFFFFFFFFFFFFFFFFUL;

+  }

+

+  return (UINT64)ArmGenericTimerGetTimerFreq ();

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
new file mode 100644
index 0000000..03a4b1e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
@@ -0,0 +1,38 @@
+#/** @file

+#

+#  Copyright (c) 2011 - 2014, ARM Limited. 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                      = ArmArchTimerLib

+  FILE_GUID                      = 82da1b44-d2d6-4a7d-bbf0-a0cb67964034

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = TimerLib

+  CONSTRUCTOR                    = TimerConstructor

+

+[Sources.common]

+  ArmArchTimerLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  DebugLib

+  ArmLib

+  BaseLib

+  ArmGenericTimerCounterLib

+

+[Pcd]

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c
new file mode 100644
index 0000000..8501e5c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c
@@ -0,0 +1,127 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/PcdLib.h>

+

+VOID

+CacheRangeOperation (

+  IN  VOID            *Start,

+  IN  UINTN           Length,

+  IN  CACHE_OPERATION CacheOperation,

+  IN  LINE_OPERATION  LineOperation

+  )

+{

+  UINTN ArmCacheLineLength         = ArmDataCacheLineLength();

+  UINTN ArmCacheLineAlignmentMask  = ArmCacheLineLength - 1;

+  UINTN ArmCacheOperationThreshold = PcdGet32(PcdArmCacheOperationThreshold);

+

+  if ((CacheOperation != NULL) && (Length >= ArmCacheOperationThreshold)) {

+    ArmDrainWriteBuffer ();

+    CacheOperation ();

+  } else {

+    // Align address (rounding down)

+    UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);

+    UINTN EndAddress     = (UINTN)Start + Length;

+

+    // Perform the line operation on an address in each cache line

+    while (AlignedAddress < EndAddress) {

+      LineOperation(AlignedAddress);

+      AlignedAddress += ArmCacheLineLength;

+    }

+  }

+}

+

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+  ArmCleanDataCache();

+  ArmInvalidateInstructionCache();

+}

+

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+  ArmInvalidateDataCache();

+}

+

+VOID *

+EFIAPI

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  CacheRangeOperation (Address, Length, ArmCleanDataCacheToPoU, ArmCleanDataCacheEntryByMVA);

+  ArmInvalidateInstructionCache ();

+  return Address;

+}

+

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+  ArmCleanInvalidateDataCache();

+}

+

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCache, ArmCleanInvalidateDataCacheEntryByMVA);

+  return Address;

+}

+

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+  ArmCleanDataCache();

+}

+

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  CacheRangeOperation(Address, Length, ArmCleanDataCache, ArmCleanDataCacheEntryByMVA);

+  return Address;

+}

+

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  CacheRangeOperation(Address, Length, NULL, ArmInvalidateDataCacheEntryByMVA);

+  return Address;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
new file mode 100644
index 0000000..5910db0
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
@@ -0,0 +1,36 @@
+#/** @file

+#  Implement CacheMaintenanceLib for ARM architectures

+#

+#  Copyright (c) 2008, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmCacheMaintenanceLib

+  FILE_GUID                      = 1A20BE1F-33AD-450C-B49A-7123FCA8B7F9

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = CacheMaintenanceLib

+

+[Sources.common]

+  ArmCacheMaintenanceLib.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  ArmLib

+  BaseLib

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/Aarch64Disassembler.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/Aarch64Disassembler.c
new file mode 100644
index 0000000..3ecae77
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/Aarch64Disassembler.c
@@ -0,0 +1,48 @@
+/** @file

+  Default exception handler

+

+  Copyright (c) 2014, ARM Limited. All rights reserved.

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD

+  License which accompanies this distribution.  The full text of the license may

+  be found at http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/PrintLib.h>

+#include <Library/ArmDisassemblerLib.h>

+

+/**

+  Place a disassembly of of **OpCodePtr into buffer, and update OpCodePtr to

+  point to next instruction.

+

+  @param  OpCodePtrPtr  Pointer to pointer of instruction to disassemble.

+  @param  Thumb         TRUE for Thumb(2), FALSE for ARM instruction stream

+  @param  Extended      TRUE dump hex for instruction too.

+  @param  ItBlock       Size of IT Block

+  @param  Buf           Buffer to sprintf disassembly into.

+  @param  Size          Size of Buf in bytes.

+

+**/

+VOID

+DisassembleInstruction (

+  IN  UINT8     **OpCodePtr,

+  IN  BOOLEAN   Thumb,

+  IN  BOOLEAN   Extended,

+  IN OUT UINT32 *ItBlock,

+  OUT CHAR8     *Buf,

+  OUT UINTN     Size

+  )

+{

+  // Not yet supported for AArch64.

+  // Put error in the buffer as we have no return code and the buffer may be

+  // printed directly so needs a '\0'.

+  AsciiSPrint (Buf, Size, "AArch64 not supported");

+  return;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
new file mode 100644
index 0000000..29a8d44
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
@@ -0,0 +1,457 @@
+/** @file

+  Default exception handler

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/PrintLib.h>

+#include <Library/ArmDisassemblerLib.h>

+

+CHAR8 *gCondition[] = {

+  "EQ",

+  "NE",

+  "CS",

+  "CC",

+  "MI",

+  "PL",

+  "VS",

+  "VC",

+  "HI",

+  "LS",

+  "GE",

+  "LT",

+  "GT",

+  "LE",

+  "",

+  "2"

+};

+

+#define COND(_a)  gCondition[((_a) >> 28)]

+

+CHAR8 *gReg[] = {

+  "r0",

+  "r1",

+  "r2",

+  "r3",

+  "r4",

+  "r5",

+  "r6",

+  "r7",

+  "r8",

+  "r9",

+  "r10",

+  "r11",

+  "r12",

+  "sp",

+  "lr",

+  "pc"

+};

+

+CHAR8 *gLdmAdr[] = {

+  "DA",

+  "IA",

+  "DB",

+  "IB"

+};

+

+CHAR8 *gLdmStack[] = {

+  "FA",

+  "FD",

+  "EA",

+  "ED"

+};

+

+#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])

+

+

+#define SIGN(_U)  ((_U) ? "" : "-")

+#define WRITE(_W) ((_W) ? "!" : "")

+#define BYTE(_B)  ((_B) ? "B":"")

+#define USER(_B)  ((_B) ? "^" : "")

+

+CHAR8 mMregListStr[4*15 + 1];

+

+CHAR8 *

+MRegList (

+  UINT32  OpCode

+  )

+{

+  UINTN     Index, Start, End;

+  CHAR8     *Str;

+  BOOLEAN   First;

+

+  Str = mMregListStr;

+  *Str = '\0';

+  AsciiStrCat  (Str, "{");

+  for (Index = 0, First = TRUE; Index <= 15; Index++) {

+    if ((OpCode & (1 << Index)) != 0) {

+      Start = End = Index;

+      for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {

+        End = Index;

+      }

+

+      if (!First) {

+        AsciiStrCat  (Str, ",");

+      } else {

+        First = FALSE;

+      }

+

+      if (Start == End) {

+        AsciiStrCat  (Str, gReg[Start]);

+        AsciiStrCat  (Str, ", ");

+      } else {

+        AsciiStrCat  (Str, gReg[Start]);

+        AsciiStrCat  (Str, "-");

+        AsciiStrCat  (Str, gReg[End]);

+      }

+    }

+  }

+  if (First) {

+    AsciiStrCat  (Str, "ERROR");

+  }

+  AsciiStrCat  (Str, "}");

+

+  // BugBug: Make caller pass in buffer it is cleaner

+  return mMregListStr;

+}

+

+CHAR8 *

+FieldMask (

+  IN  UINT32  Mask

+  )

+{

+  return "";

+}

+

+UINT32

+RotateRight (

+  IN UINT32 Op,

+  IN UINT32 Shift

+  )

+{

+  return (Op >> Shift) | (Op << (32 - Shift));

+}

+

+

+/**

+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to

+  point to next instructin.

+

+  We cheat and only decode instructions that access

+  memory. If the instruction is not found we dump the instruction in hex.

+

+  @param  OpCodePtr   Pointer to pointer of ARM instruction to disassemble.

+  @param  Buf         Buffer to sprintf disassembly into.

+  @param  Size        Size of Buf in bytes.

+  @param  Extended    TRUE dump hex for instruction too.

+

+**/

+VOID

+DisassembleArmInstruction (

+  IN  UINT32    **OpCodePtr,

+  OUT CHAR8     *Buf,

+  OUT UINTN     Size,

+  IN  BOOLEAN   Extended

+  )

+{

+  UINT32    OpCode = **OpCodePtr;

+  CHAR8     *Type, *Root;

+  BOOLEAN   I, P, U, B, W, L, S, H;

+  UINT32    Rn, Rd, Rm;

+  UINT32    imode, offset_8, offset_12;

+  UINT32    Index;

+  UINT32    shift_imm, shift;

+

+  I = (OpCode & BIT25) == BIT25;

+  P = (OpCode & BIT24) == BIT24;

+  U = (OpCode & BIT23) == BIT23;

+  B = (OpCode & BIT22) == BIT22;  // Also called S

+  W = (OpCode & BIT21) == BIT21;

+  L = (OpCode & BIT20) == BIT20;

+  S = (OpCode & BIT6) == BIT6;

+  H = (OpCode & BIT5) == BIT5;

+  Rn = (OpCode >> 16) & 0xf;

+  Rd = (OpCode >> 12) & 0xf;

+  Rm = (OpCode & 0xf);

+

+

+  if (Extended) {

+    Index = AsciiSPrint (Buf, Size, "0x%08x   ", OpCode);

+    Buf += Index;

+    Size -= Index;

+  }

+

+  // LDREX, STREX

+  if ((OpCode  & 0x0fe000f0) == 0x01800090) {

+    if (L) {

+      // A4.1.27  LDREX{<cond>} <Rd>, [<Rn>]

+      AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);

+    } else {

+     // A4.1.103  STREX{<cond>} <Rd>, <Rm>, [<Rn>]

+      AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);

+    }

+    return;

+  }

+

+  // LDM/STM

+  if ((OpCode  & 0x0e000000) == 0x08000000) {

+    if (L) {

+      // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>

+      // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^

+      // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^

+      AsciiSPrint (Buf, Size, "LDM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B));

+    } else {

+      // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>

+      // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^

+      AsciiSPrint (Buf, Size, "STM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B));

+    }

+    return;

+  }

+

+  // LDR/STR Address Mode 2

+  if ( ((OpCode  & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {

+    offset_12 = OpCode & 0xfff;

+    if ((OpCode & 0xfd70f000 ) == 0xf550f000) {

+      Index = AsciiSPrint (Buf, Size, "PLD");

+    } else {

+      Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", L ? "LDR" : "STR", COND (OpCode), BYTE (B), (!(P) && W) ? "T":"", gReg[Rd]);

+    }

+    if (P) {

+      if (!I) {

+        // A5.2.2 [<Rn>, #+/-<offset_12>]

+        // A5.2.5 [<Rn>, #+/-<offset_12>]

+        AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (U), offset_12, WRITE (W));

+      } else if ((OpCode & 0x03000ff0) == 0x03000000) {

+        // A5.2.3 [<Rn>, +/-<Rm>]

+        // A5.2.6 [<Rn>, +/-<Rm>]!

+        AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (U), WRITE (W));

+      } else {

+        // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]

+        // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!

+        shift_imm = (OpCode >> 7) & 0x1f;

+        shift = (OpCode >> 5) & 0x3;

+        if (shift == 0x0) {

+          Type = "LSL";

+        } else if (shift == 0x1) {

+          Type = "LSR";

+          if (shift_imm == 0) {

+            shift_imm = 32;

+          }

+        } else if (shift == 0x12) {

+          Type = "ASR";

+        } else if (shift_imm == 0) {

+          AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));

+          return;

+        } else {

+          Type = "ROR";

+        }

+

+        AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm, WRITE (W));

+      }

+    } else {  // !P

+      if (!I) {

+        // A5.2.8  [<Rn>], #+/-<offset_12>

+        AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (U), offset_12);

+      } else if ((OpCode & 0x03000ff0) == 0x03000000) {

+        // A5.2.9  [<Rn>], +/-<Rm>

+        AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);

+      } else {

+        // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>

+        shift_imm = (OpCode >> 7) & 0x1f;

+        shift = (OpCode >> 5) & 0x3;

+

+        if (shift == 0x0) {

+          Type = "LSL";

+        } else if (shift == 0x1) {

+          Type = "LSR";

+          if (shift_imm == 0) {

+            shift_imm = 32;

+          }

+        } else if (shift == 0x12) {

+          Type = "ASR";

+        } else if (shift_imm == 0) {

+          AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);

+          // FIx me

+          return;

+        } else {

+          Type = "ROR";

+        }

+

+        AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm);

+      }

+    }

+    return;

+  }

+

+  if ((OpCode  & 0x0e000000) == 0x00000000) {

+    // LDR/STR address mode 3

+    // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>

+    if (L) {

+      if (!S) {

+        Root = "LDR%aH %a, ";

+      } else if (!H) {

+        Root = "LDR%aSB %a, ";

+      } else {

+        Root = "LDR%aSH %a, ";

+      }

+    } else {

+      if (!S) {

+        Root = "STR%aH %a ";

+      } else if (!H) {

+        Root = "LDR%aD %a ";

+      } else {

+        Root = "STR%aD %a ";

+      }

+    }

+

+    Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]);

+

+    S = (OpCode & BIT6) == BIT6;

+    H = (OpCode & BIT5) == BIT5;

+    offset_8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;

+    if (P & !W) {

+      // Immediate offset/index

+      if (B) {

+        // A5.3.2  [<Rn>, #+/-<offset_8>]

+        // A5.3.4  [<Rn>, #+/-<offset_8>]!

+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (U), offset_8, WRITE (W));

+      } else {

+        // A5.3.3  [<Rn>, +/-<Rm>]

+        // A5.3.5  [<Rn>, +/-<Rm>]!

+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));

+      }

+    } else {

+      // Register offset/index

+      if (B) {

+        // A5.3.6 [<Rn>], #+/-<offset_8>

+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (U), offset_8);

+      } else {

+        // A5.3.7 [<Rn>], +/-<Rm>

+        AsciiSPrint  (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);

+      }

+    }

+    return;

+  }

+

+  if ((OpCode  & 0x0fb000f0) == 0x01000050) {

+    // A4.1.108  SWP   SWP{<cond>}B <Rd>, <Rm>, [<Rn>]

+    // A4.1.109  SWPB  SWP{<cond>}B <Rd>, <Rm>, [<Rn>]

+    AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (B), gReg[Rd], gReg[Rm], gReg[Rn]);

+    return;

+  }

+

+  if ((OpCode  & 0xfe5f0f00) == 0xf84d0500) {

+    // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}

+    AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (W));

+    return;

+  }

+

+  if ((OpCode  & 0xfe500f00) == 0xf8100500) {

+    // A4.1.59 RFE<addressing_mode> <Rn>{!}

+    AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (W));

+    return;

+  }

+

+  if ((OpCode  & 0xfff000f0) == 0xe1200070) {

+    // A4.1.7 BKPT <immed_16>

+    AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);

+    return;

+  }

+

+  if ((OpCode  & 0xfff10020) == 0xf1000000) {

+    // A4.1.16 CPS<effect> <iflags> {, #<mode>}

+    if (((OpCode >> 6) & 0x7) == 0) {

+      AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));

+    } else {

+      imode = (OpCode >> 18) & 0x3;

+      Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");

+      if ((OpCode & BIT17) != 0) {

+        AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);

+      }

+    }

+    return;

+  }

+

+  if ((OpCode  & 0x0f000000) == 0x0f000000) {

+    // A4.1.107 SWI{<cond>} <immed_24>

+    AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);

+    return;

+  }

+

+  if ((OpCode  & 0x0fb00000) == 0x01000000) {

+    // A4.1.38 MRS{<cond>} <Rd>, CPSR  MRS{<cond>} <Rd>, SPSR

+    AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], B ? "SPSR" : "CPSR");

+    return;

+  }

+

+

+  if ((OpCode  & 0x0db00000) == 0x03200000) {

+    // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>

+    if (I) {

+      // MSR{<cond>} CPSR_<fields>, #<immediate>

+      AsciiSPrint (Buf, Size, "MRS%a %a_%a, #0x%x", COND (OpCode),  B ? "SPSR" : "CPSR", FieldMask ((OpCode >> 16) & 0xf), RotateRight (OpCode & 0xf, ((OpCode >> 8) & 0xf) *2));

+    } else {

+      // MSR{<cond>} CPSR_<fields>, <Rm>

+      AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), B ? "SPSR" : "CPSR", gReg[Rd]);

+    }

+    return;

+  }

+

+  if ((OpCode  & 0xff000010) == 0xfe000000) {

+    // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>

+    AsciiSPrint (Buf, Size, "CDP%a 0x%x, 0x%x, CR%d, CR%d, CR%d, 0x%x", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, Rn, Rd, Rm, (OpCode >> 5) &0x7);

+    return;

+  }

+

+  if ((OpCode  & 0x0e000000) == 0x0c000000) {

+    // A4.1.19 LDC and A4.1.96 SDC

+    if ((OpCode & 0xf0000000) == 0xf0000000) {

+      Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", L ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);

+    } else {

+      Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ",  L ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);

+    }

+

+    if (!P) {

+      if (!W) {

+        // A5.5.5.5 [<Rn>], <option>

+      AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff);

+      } else {

+        // A.5.5.4  [<Rn>], #+/-<offset_8>*4

+      AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (U), OpCode & 0xff);

+      }

+    } else {

+      // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!

+      AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (U), OpCode & 0xff, WRITE (W));

+    }

+

+  }

+

+  if ((OpCode  & 0x0f000010) == 0x0e000010) {

+    // A4.1.32 MRC2, MCR2

+    AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", L ? "MRC":"MCR", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], Rn, Rm, (OpCode >> 5) &0x7);

+    return;

+  }

+

+  if ((OpCode  & 0x0ff00000) == 0x0c400000) {

+    // A4.1.33 MRRC2, MCRR2

+    AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, %a, CR%d", L ? "MRRC":"MCRR", COND (OpCode), (OpCode >> 4) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], gReg[Rn], Rm);

+    return;

+  }

+

+  AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);

+

+  *OpCodePtr += 1;

+  return;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
new file mode 100644
index 0000000..bb51e30
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
@@ -0,0 +1,40 @@
+#/** @file

+#  ARM Disassembler library

+#

+#  Copyright (c) 2008, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmDisassemblerLib

+  FILE_GUID                      = 7ACEC173-F15D-426C-8F2F-BD86B4183EF1

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmDisassemblerLib

+

+

+[Sources.ARM]

+  ArmDisassembler.c

+  ThumbDisassembler.c

+

+[Sources.AARCH64]

+  Aarch64Disassembler.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  PrintLib

+  DebugLib

+  PeCoffGetEntryPointLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
new file mode 100644
index 0000000..5bad3af
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
@@ -0,0 +1,1064 @@
+/** @file

+  Thumb Dissassembler. Still a work in progress.

+

+  Wrong output is a bug, so please fix it.

+  Hex output means there is not yet an entry or a decode bug.

+  gOpThumb[] are Thumb 16-bit, and gOpThumb2[] work on the 32-bit

+  16-bit stream of Thumb2 instruction. Then there are big case

+  statements to print everything out. If you are adding instructions

+  try to reuse existing case entries if possible.

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PrintLib.h>

+

+extern CHAR8 *gCondition[];

+

+extern CHAR8 *gReg[];

+

+// Thumb address modes

+#define LOAD_STORE_FORMAT1            1

+#define LOAD_STORE_FORMAT1_H        101

+#define LOAD_STORE_FORMAT1_B        111

+#define LOAD_STORE_FORMAT2            2

+#define LOAD_STORE_FORMAT3            3

+#define LOAD_STORE_FORMAT4            4

+#define LOAD_STORE_MULTIPLE_FORMAT1   5

+#define PUSH_FORMAT                   6

+#define POP_FORMAT                  106

+#define IMMED_8                       7

+#define CONDITIONAL_BRANCH            8

+#define UNCONDITIONAL_BRANCH          9

+#define UNCONDITIONAL_BRANCH_SHORT  109

+#define BRANCH_EXCHANGE              10

+#define DATA_FORMAT1                 11

+#define DATA_FORMAT2                 12

+#define DATA_FORMAT3                 13

+#define DATA_FORMAT4                 14

+#define DATA_FORMAT5                 15

+#define DATA_FORMAT6_SP              16

+#define DATA_FORMAT6_PC             116

+#define DATA_FORMAT7                 17

+#define DATA_FORMAT8                 19

+#define CPS_FORMAT                   20

+#define ENDIAN_FORMAT                21

+#define DATA_CBZ                     22

+#define ADR_FORMAT                   23

+#define IT_BLOCK                     24

+

+// Thumb2 address modes

+#define B_T3                        200

+#define B_T4                        201

+#define BL_T2                       202

+#define POP_T2                      203

+#define POP_T3                      204

+#define STM_FORMAT                  205

+#define LDM_REG_IMM12_SIGNED        206

+#define LDM_REG_IMM12_LSL           207

+#define LDM_REG_IMM8                208

+#define LDM_REG_IMM12               209

+#define LDM_REG_INDIRECT_LSL        210

+#define LDM_REG_IMM8_SIGNED         211

+#define LDRD_REG_IMM8               212

+#define LDREXB                      213

+#define LDREXD                      214

+#define SRS_FORMAT                  215

+#define RFE_FORMAT                  216

+#define LDRD_REG_IMM8_SIGNED        217

+#define ADD_IMM12                   218

+#define ADD_IMM5                    219

+#define ADR_THUMB2                  220

+#define CMN_THUMB2                  221

+#define ASR_IMM5                    222

+#define ASR_3REG                    223

+#define BFC_THUMB2                  224

+#define CDP_THUMB2                  225

+#define THUMB2_NO_ARGS              226

+#define THUMB2_2REGS                227

+#define ADD_IMM5_2REG               228

+#define CPD_THUMB2                  229

+#define THUMB2_4REGS                230

+#define ADD_IMM12_1REG              231

+#define THUMB2_IMM16                232

+#define MRC_THUMB2                  233

+#define MRRC_THUMB2                 234

+#define THUMB2_MRS                  235

+#define THUMB2_MSR                  236

+

+

+

+

+typedef struct {

+  CHAR8   *Start;

+  UINT32  OpCode;

+  UINT32  Mask;

+  UINT32  AddressMode;

+} THUMB_INSTRUCTIONS;

+

+THUMB_INSTRUCTIONS gOpThumb[] = {

+// Thumb 16-bit instrucitons

+//          Op       Mask   Format

+  { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },  // ADC <Rndn>, <Rm>

+  { "ADR",  0xa000, 0xf800, ADR_FORMAT   },  // ADR <Rd>, <label>

+  { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },

+  { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },

+  { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },

+  { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 },   // A8.6.9

+  { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },

+  { "ADD" , 0xa800, 0xf800, DATA_FORMAT6_SP },

+  { "ADD" , 0xb000, 0xff80, DATA_FORMAT7 },

+

+  { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },

+

+  { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },

+  { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },

+

+  { "B"   , 0xd000, 0xf000, CONDITIONAL_BRANCH },

+  { "B"   , 0xe000, 0xf800, UNCONDITIONAL_BRANCH_SHORT },

+  { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },

+  { "BX"  , 0x4700, 0xff87, BRANCH_EXCHANGE },

+

+  { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },

+  { "BKPT", 0xdf00, 0xff00, IMMED_8 },

+  { "CBZ",  0xb100, 0xfd00, DATA_CBZ },

+  { "CBNZ", 0xb900, 0xfd00, DATA_CBZ },

+  { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },

+

+  { "CMP" , 0x2800, 0xf800, DATA_FORMAT3 },

+  { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },

+  { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },

+

+  { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },

+  { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },

+  { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },

+

+  { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },

+  { "LDR"   , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },  // LDR <Rt>, [<Rn> {,#<imm>}]

+  { "LDR"   , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },  // STR <Rt>, [<Rn>, <Rm>]

+  { "LDR"   , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },

+  { "LDR"   , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },  // LDR <Rt>, [SP, #<imm>]

+  { "LDRB"  , 0x7800, 0xf800, LOAD_STORE_FORMAT1_B },

+  { "LDRB"  , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },  // STR <Rt>, [<Rn>, <Rm>]

+  { "LDRH"  , 0x8800, 0xf800, LOAD_STORE_FORMAT1_H },

+  { "LDRH"  , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },

+  { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },  // STR <Rt>, [<Rn>, <Rm>]

+  { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },

+

+  { "MOVS", 0x0000, 0xffc0, DATA_FORMAT5 },   // LSL with imm5 == 0 is a MOVS, so this must go before LSL

+  { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },

+  { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },

+  { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },

+  { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },

+  { "LSRS", 0x0800, 0xf800, DATA_FORMAT4 },  // LSRS <Rd>, <Rm>, #<imm5>

+

+  { "MOVS", 0x2000, 0xf800, DATA_FORMAT3 },

+  { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },

+  { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },

+

+  { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },

+  { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },

+  { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },

+  { "ORR" , 0x4300, 0xffc0, DATA_FORMAT5 },

+  { "POP" , 0xbc00, 0xfe00, POP_FORMAT },

+  { "PUSH", 0xb400, 0xfe00, PUSH_FORMAT },

+

+  { "REV"   , 0xba00, 0xffc0, DATA_FORMAT5 },

+  { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },

+  { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },

+

+  { "ROR"    , 0x41c0, 0xffc0, DATA_FORMAT5 },

+  { "SBC"    , 0x4180, 0xffc0, DATA_FORMAT5 },

+  { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },

+

+  { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },

+  { "STR"   , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },   // STR  <Rt>, [<Rn> {,#<imm>}]

+  { "STR"   , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },   // STR  <Rt>, [<Rn>, <Rm>]

+  { "STR"   , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },   // STR  <Rt>, [SP, #<imm>]

+  { "STRB"  , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B }, // STRB <Rt>, [<Rn>, #<imm5>]

+  { "STRB"  , 0x5400, 0xfe00, LOAD_STORE_FORMAT2 },   // STRB <Rt>, [<Rn>, <Rm>]

+  { "STRH"  , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H }, // STRH <Rt>, [<Rn>{,#<imm>}]

+  { "STRH"  , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },   // STRH <Rt>, [<Rn>, <Rm>]

+

+  { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },

+  { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },

+  { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },

+  { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },

+

+  { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },

+

+  { "SWI" , 0xdf00, 0xff00, IMMED_8 },

+  { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },

+  { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },

+  { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },

+  { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },

+  { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 },

+

+  { "IT",   0xbf00, 0xff00, IT_BLOCK }

+

+};

+

+THUMB_INSTRUCTIONS gOpThumb2[] = {

+//Instruct  OpCode      OpCode Mask  Addressig Mode

+

+  { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2    },  // ADDR <Rd>, <label> ;Needs to go before ADDW

+  { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2    },  // CMN <Rn>, #<const> ;Needs to go before ADD

+  { "CMN", 0xeb100f00, 0xfff08f00, ADD_IMM5_2REG },  // CMN <Rn>, <Rm> {,<shift> #<const>}

+  { "CMP", 0xf1a00f00, 0xfff08f00, CMN_THUMB2    },  // CMP <Rn>, #<const>

+  { "TEQ", 0xf0900f00, 0xfff08f00, CMN_THUMB2    },  // CMP <Rn>, #<const>

+  { "TEQ", 0xea900f00, 0xfff08f00, ADD_IMM5_2REG },  // CMN <Rn>, <Rm> {,<shift> #<const>}

+  { "TST", 0xf0100f00, 0xfff08f00, CMN_THUMB2    },  // CMP <Rn>, #<const>

+  { "TST", 0xea100f00, 0xfff08f00, ADD_IMM5_2REG },  // TST <Rn>, <Rm> {,<shift> #<const>}

+

+  { "MOV",  0xf04f0000, 0xfbef8000, ADD_IMM12_1REG }, // MOV  <Rd>, #<const>

+  { "MOVW", 0xf2400000, 0xfbe08000, THUMB2_IMM16 },   // MOVW <Rd>, #<const>

+  { "MOVT", 0xf2c00000, 0xfbe08000, THUMB2_IMM16 },   // MOVT <Rd>, #<const>

+

+  { "ADC",  0xf1400000, 0xfbe08000, ADD_IMM12 }, // ADC{S}  <Rd>, <Rn>, #<const>

+  { "ADC",  0xeb400000, 0xffe08000, ADD_IMM5  }, // ADC{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "ADD",  0xf1000000, 0xfbe08000, ADD_IMM12 }, // ADD{S}  <Rd>, <Rn>, #<const>

+  { "ADD",  0xeb000000, 0xffe08000, ADD_IMM5  }, // ADD{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "ADDW", 0xf2000000, 0xfbe08000, ADD_IMM12 }, // ADDW{S} <Rd>, <Rn>, #<const>

+  { "AND",  0xf0000000, 0xfbe08000, ADD_IMM12 }, // AND{S}  <Rd>, <Rn>, #<const>

+  { "AND",  0xea000000, 0xffe08000, ADD_IMM5  }, // AND{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "BIC",  0xf0200000, 0xfbe08000, ADD_IMM12 }, // BIC{S}  <Rd>, <Rn>, #<const>

+  { "BIC",  0xea200000, 0xffe08000, ADD_IMM5  }, // BIC{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "EOR",  0xf0800000, 0xfbe08000, ADD_IMM12 }, // EOR{S}  <Rd>, <Rn>, #<const>

+  { "EOR",  0xea800000, 0xffe08000, ADD_IMM5  }, // EOR{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "ORN",  0xf0600000, 0xfbe08000, ADD_IMM12 }, // ORN{S}  <Rd>, <Rn>, #<const>

+  { "ORN",  0xea600000, 0xffe08000, ADD_IMM5  }, // ORN{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "ORR",  0xf0400000, 0xfbe08000, ADD_IMM12 }, // ORR{S}  <Rd>, <Rn>, #<const>

+  { "ORR",  0xea400000, 0xffe08000, ADD_IMM5  }, // ORR{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "RSB",  0xf1c00000, 0xfbe08000, ADD_IMM12 }, // RSB{S}  <Rd>, <Rn>, #<const>

+  { "RSB",  0xebc00000, 0xffe08000, ADD_IMM5  }, // RSB{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "SBC",  0xf1600000, 0xfbe08000, ADD_IMM12 }, // SBC{S}  <Rd>, <Rn>, #<const>

+  { "SBC",  0xeb600000, 0xffe08000, ADD_IMM5  }, // SBC{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+  { "SUB",  0xf1a00000, 0xfbe08000, ADD_IMM12 }, // SUB{S}  <Rd>, <Rn>, #<const>

+  { "SUB",  0xeba00000, 0xffe08000, ADD_IMM5  }, // SUB{S}  <Rd>, <Rn>, <Rm> {,<shift> #<const>}

+

+  { "ASR",  0xea4f0020, 0xffef8030, ASR_IMM5 },  // ARS  <Rd>, <Rm> #<const>} imm3:imm2

+  { "ASR",  0xfa40f000, 0xffe0f0f0, ASR_3REG },  // ARS  <Rd>, <Rn>, <Rm>

+  { "LSR",  0xea4f0010, 0xffef8030, ASR_IMM5 },  // LSR  <Rd>, <Rm> #<const>} imm3:imm2

+  { "LSR",  0xfa20f000, 0xffe0f0f0, ASR_3REG },  // LSR  <Rd>, <Rn>, <Rm>

+  { "ROR",  0xea4f0030, 0xffef8030, ASR_IMM5 },  // ROR  <Rd>, <Rm> #<const>} imm3:imm2

+  { "ROR",  0xfa60f000, 0xffe0f0f0, ASR_3REG },  // ROR  <Rd>, <Rn>, <Rm>

+

+  { "BFC",  0xf36f0000, 0xffff8010, BFC_THUMB2 },   // BFC  <Rd>, #<lsb>, #<width>

+  { "BIC",  0xf3600000, 0xfff08010, BFC_THUMB2 },   // BIC  <Rn>, <Rd>, #<lsb>, #<width>

+  { "SBFX", 0xf3400000, 0xfff08010, BFC_THUMB2 },   // SBFX <Rn>, <Rd>, #<lsb>, #<width>

+  { "UBFX", 0xf3c00000, 0xfff08010, BFC_THUMB2 },   // UBFX <Rn>, <Rd>, #<lsb>, #<width>

+

+  { "CPD",  0xee000000, 0xff000010, CPD_THUMB2 },  // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>

+  { "CPD2", 0xfe000000, 0xff000010, CPD_THUMB2 },  // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>

+

+  { "MRC",   0xee100000, 0xff100000, MRC_THUMB2 },  // MRC  <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>

+  { "MRC2",  0xfe100000, 0xff100000, MRC_THUMB2 },  // MRC2 <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>

+  { "MRRC",  0xec500000, 0xfff00000, MRRC_THUMB2 },  // MRRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>

+  { "MRRC2", 0xfc500000, 0xfff00000, MRRC_THUMB2 },  // MRR2 <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>

+

+  { "MRS",   0xf3ef8000, 0xfffff0ff, THUMB2_MRS  }, // MRS  <Rd>, CPSR

+  { "MSR",   0xf3808000, 0xfff0fcff, THUMB2_MSR  }, // MSR  CPSR_fs, <Rn>

+

+  { "CLREX", 0xf3bf8f2f, 0xfffffff, THUMB2_NO_ARGS }, // CLREX

+

+  { "CLZ",   0xfab0f080, 0xfff0f0f0, THUMB2_2REGS },  // CLZ    <Rd>,<Rm>

+  { "MOV",   0xec4f0000, 0xfff0f0f0, THUMB2_2REGS },  // MOV    <Rd>,<Rm>

+  { "MOVS",  0xec5f0000, 0xfff0f0f0, THUMB2_2REGS },  // MOVS   <Rd>,<Rm>

+  { "RBIT",  0xfb90f0a0, 0xfff0f0f0, THUMB2_2REGS },  // RBIT   <Rd>,<Rm>

+  { "REV",   0xfb90f080, 0xfff0f0f0, THUMB2_2REGS },  // REV    <Rd>,<Rm>

+  { "REV16", 0xfa90f090, 0xfff0f0f0, THUMB2_2REGS },  // REV16  <Rd>,<Rm>

+  { "REVSH", 0xfa90f0b0, 0xfff0f0f0, THUMB2_2REGS },  // REVSH  <Rd>,<Rm>

+  { "RRX",   0xea4f0030, 0xfffff0f0, THUMB2_2REGS },  // RRX    <Rd>,<Rm>

+  { "RRXS",  0xea5f0030, 0xfffff0f0, THUMB2_2REGS },  // RRXS   <Rd>,<Rm>

+

+  { "MLA",   0xfb000000, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>

+  { "MLS",   0xfb000010, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>

+

+

+  { "SMLABB",  0xfb100000, 0xfff000f0, THUMB2_4REGS }, // SMLABB   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLABT",  0xfb100010, 0xfff000f0, THUMB2_4REGS }, // SMLABT   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLABB",  0xfb100020, 0xfff000f0, THUMB2_4REGS }, // SMLATB   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLATT",  0xfb100030, 0xfff000f0, THUMB2_4REGS }, // SMLATT   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLAWB",  0xfb300000, 0xfff000f0, THUMB2_4REGS }, // SMLAWB   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLAWT",  0xfb300010, 0xfff000f0, THUMB2_4REGS }, // SMLAWT   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLSD",   0xfb400000, 0xfff000f0, THUMB2_4REGS }, // SMLSD    <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLSDX",  0xfb400010, 0xfff000f0, THUMB2_4REGS }, // SMLSDX   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMMLA",   0xfb500000, 0xfff000f0, THUMB2_4REGS }, // SMMLA    <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMMLAR",  0xfb500010, 0xfff000f0, THUMB2_4REGS }, // SMMLAR   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMMLS",   0xfb600000, 0xfff000f0, THUMB2_4REGS }, // SMMLS    <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMMLSR",  0xfb600010, 0xfff000f0, THUMB2_4REGS }, // SMMLSR   <Rd>, <Rn>, <Rm>, <Ra>

+  { "USADA8",  0xfb700000, 0xfff000f0, THUMB2_4REGS }, // USADA8   <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLAD",   0xfb200000, 0xfff000f0, THUMB2_4REGS }, // SMLAD    <Rd>, <Rn>, <Rm>, <Ra>

+  { "SMLADX",  0xfb200010, 0xfff000f0, THUMB2_4REGS }, // SMLADX   <Rd>, <Rn>, <Rm>, <Ra>

+

+

+  { "B",    0xf0008000, 0xf800d000, B_T3  },             // B<c> <label>

+  { "B",    0xf0009000, 0xf800d000, B_T4  },             // B<c> <label>

+  { "BL",   0xf000d000, 0xf800d000, B_T4  },             // BL<c> <label>

+  { "BLX",  0xf000c000, 0xf800d000, BL_T2 },             // BLX<c> <label>

+

+  { "POP",   0xe8bd0000, 0xffff2000, POP_T2 },           // POP <registers>

+  { "POP",   0xf85d0b04, 0xffff0fff, POP_T3 },           // POP <register>

+  { "PUSH",  0xe8ad0000, 0xffffa000, POP_T2 },           // PUSH <registers>

+  { "PUSH",  0xf84d0d04, 0xffff0fff, POP_T3 },           // PUSH <register>

+  { "STM"  , 0xe8800000, 0xffd0a000,  STM_FORMAT },      // STM <Rn>{!},<registers>

+  { "STMDB", 0xe9800000, 0xffd0a000,  STM_FORMAT },      // STMDB <Rn>{!},<registers>

+  { "LDM"  , 0xe8900000, 0xffd02000,  STM_FORMAT },      // LDM <Rn>{!},<registers>

+  { "LDMDB", 0xe9100000, 0xffd02000,  STM_FORMAT },      // LDMDB <Rn>{!},<registers>

+

+  { "LDR",   0xf8d00000, 0xfff00000,  LDM_REG_IMM12 },          // LDR   <rt>, [<rn>, {, #<imm12>]}

+  { "LDRB",  0xf8900000, 0xfff00000,  LDM_REG_IMM12 },          // LDRB  <rt>, [<rn>, {, #<imm12>]}

+  { "LDRH",  0xf8b00000, 0xfff00000,  LDM_REG_IMM12 },          // LDRH  <rt>, [<rn>, {, #<imm12>]}

+  { "LDRSB", 0xf9900000, 0xfff00000,  LDM_REG_IMM12 },          // LDRSB <rt>, [<rn>, {, #<imm12>]}

+  { "LDRSH", 0xf9b00000, 0xfff00000,  LDM_REG_IMM12 },          // LDRSH <rt>, [<rn>, {, #<imm12>]}

+

+  { "LDR",   0xf85f0000, 0xff7f0000,  LDM_REG_IMM12_SIGNED },   // LDR   <Rt>, <label>

+  { "LDRB",  0xf81f0000, 0xff7f0000,  LDM_REG_IMM12_SIGNED },   // LDRB  <Rt>, <label>

+  { "LDRH",  0xf83f0000, 0xff7f0000,  LDM_REG_IMM12_SIGNED },   // LDRH  <Rt>, <label>

+  { "LDRSB", 0xf91f0000, 0xff7f0000,  LDM_REG_IMM12_SIGNED },   // LDRSB <Rt>, <label>

+  { "LDRSH", 0xf93f0000, 0xff7f0000,  LDM_REG_IMM12_SIGNED },   // LDRSB <Rt>, <label>

+

+  { "LDR",   0xf8500000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // LDR   <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+  { "LDRB",  0xf8100000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // LDRB  <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+  { "LDRH",  0xf8300000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // LDRH  <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+  { "LDRSB", 0xf9100000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // LDRSB <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+  { "LDRSH", 0xf9300000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // LDRSH <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+

+  { "LDR",   0xf8500800, 0xfff00800,  LDM_REG_IMM8 },           // LDR    <rt>, [<rn>, {, #<imm8>]}

+  { "LDRBT", 0xf8100e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRBT  <rt>, [<rn>, {, #<imm8>]}

+  { "LDRHT", 0xf8300e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRHT  <rt>, [<rn>, {, #<imm8>]}

+  { "LDRSB", 0xf9100800, 0xfff00800,  LDM_REG_IMM8 },           // LDRHT  <rt>, [<rn>, {, #<imm8>]}  {!} form?

+  { "LDRSBT",0xf9100e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRHBT <rt>, [<rn>, {, #<imm8>]}  {!} form?

+  { "LDRSH" ,0xf9300800, 0xfff00800,  LDM_REG_IMM8 },           // LDRSH  <rt>, [<rn>, {, #<imm8>]}

+  { "LDRSHT",0xf9300e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRSHT <rt>, [<rn>, {, #<imm8>]}

+  { "LDRT",  0xf8500e00, 0xfff00f00,  LDM_REG_IMM8 },           // LDRT   <rt>, [<rn>, {, #<imm8>]}

+

+  { "LDRD",  0xe8500000, 0xfe500000,  LDRD_REG_IMM8_SIGNED },   // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}

+  { "LDRD",  0xe8500000, 0xfe500000,  LDRD_REG_IMM8       },    // LDRD <rt>, <rt2>, <label>

+

+  { "LDREX",  0xe8500f00, 0xfff00f00,  LDM_REG_IMM8 },           // LDREX <Rt>, [Rn, {#imm8}]]

+  { "LDREXB", 0xe8d00f4f, 0xfff00fff,  LDREXB  },                // LDREXB <Rt>, [<Rn>]

+  { "LDREXH", 0xe8d00f5f, 0xfff00fff,  LDREXB  },                // LDREXH <Rt>, [<Rn>]

+

+  { "LDREXD", 0xe8d00f4f, 0xfff00fff,  LDREXD  },                // LDREXD <Rt>, <Rt2>, [<Rn>]

+

+  { "STR",   0xf8c00000, 0xfff00000,  LDM_REG_IMM12 },          // STR   <rt>, [<rn>, {, #<imm12>]}

+  { "STRB",  0xf8800000, 0xfff00000,  LDM_REG_IMM12 },          // STRB  <rt>, [<rn>, {, #<imm12>]}

+  { "STRH",  0xf8a00000, 0xfff00000,  LDM_REG_IMM12 },          // STRH  <rt>, [<rn>, {, #<imm12>]}

+

+  { "STR",   0xf8400000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // STR   <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+  { "STRB",  0xf8000000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // STRB  <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+  { "STRH",  0xf8200000, 0xfff00fc0,  LDM_REG_INDIRECT_LSL },   // STRH  <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+

+  { "STR",   0xf8400800, 0xfff00800,  LDM_REG_IMM8 },           // STR    <rt>, [<rn>, {, #<imm8>]}

+  { "STRH",  0xf8200800, 0xfff00800,  LDM_REG_IMM8 },           // STRH   <rt>, [<rn>, {, #<imm8>]}

+  { "STRBT", 0xf8000e00, 0xfff00f00,  LDM_REG_IMM8 },           // STRBT  <rt>, [<rn>, {, #<imm8>]}

+  { "STRHT", 0xf8200e00, 0xfff00f00,  LDM_REG_IMM8 },           // STRHT  <rt>, [<rn>, {, #<imm8>]}

+  { "STRT",  0xf8400e00, 0xfff00f00,  LDM_REG_IMM8 },           // STRT   <rt>, [<rn>, {, #<imm8>]}

+

+  { "STRD",  0xe8400000, 0xfe500000,  LDRD_REG_IMM8_SIGNED },    // STRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}

+

+  { "STREX",  0xe8400f00, 0xfff00f00,  LDM_REG_IMM8 },           // STREX <Rt>, [Rn, {#imm8}]]

+  { "STREXB", 0xe8c00f4f, 0xfff00fff,  LDREXB  },                // STREXB <Rd>, <Rt>, [<Rn>]

+  { "STREXH", 0xe8c00f5f, 0xfff00fff,  LDREXB  },                // STREXH <Rd>, <Rt>, [<Rn>]

+

+  { "STREXD", 0xe8d00f4f, 0xfff00fff,  LDREXD  },                // STREXD <Rd>, <Rt>, <Rt2>, [<Rn>]

+

+  { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT },       // SRSDB<c> SP{!},#<mode>

+  { "SRS"  , 0xe98dc000, 0xffdffff0, SRS_FORMAT },       // SRS{IA}<c> SP{!},#<mode>

+  { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT },       // RFEDB<c> <Rn>{!}

+  { "RFE"  , 0xe990c000, 0xffd0ffff, RFE_FORMAT }        // RFE{IA}<c> <Rn>{!}

+};

+

+CHAR8 *gShiftType[] = {

+  "LSL",

+  "LSR",

+  "ASR",

+  "ROR"

+};

+

+CHAR8 mThumbMregListStr[4*15 + 1];

+

+CHAR8 *

+ThumbMRegList (

+  UINT32  RegBitMask

+  )

+{

+  UINTN     Index, Start, End;

+  CHAR8     *Str;

+  BOOLEAN   First;

+

+  Str = mThumbMregListStr;

+  *Str = '\0';

+  AsciiStrCat  (Str, "{");

+

+  for (Index = 0, First = TRUE; Index <= 15; Index++) {

+    if ((RegBitMask & (1 << Index)) != 0) {

+      Start = End = Index;

+      for (Index++; ((RegBitMask & (1 << Index)) != 0) && (Index <= 9); Index++) {

+        End = Index;

+      }

+

+      if (!First) {

+        AsciiStrCat  (Str, ",");

+      } else {

+        First = FALSE;

+      }

+

+      if (Start == End) {

+        AsciiStrCat  (Str, gReg[Start]);

+      } else {

+        AsciiStrCat  (Str, gReg[Start]);

+        AsciiStrCat  (Str, "-");

+        AsciiStrCat  (Str, gReg[End]);

+      }

+    }

+  }

+  if (First) {

+    AsciiStrCat  (Str, "ERROR");

+  }

+  AsciiStrCat  (Str, "}");

+

+  // BugBug: Make caller pass in buffer it is cleaner

+  return mThumbMregListStr;

+}

+

+UINT32

+SignExtend32 (

+  IN  UINT32  Data,

+  IN  UINT32  TopBit

+  )

+{

+  if (((Data & TopBit) == 0) || (TopBit == BIT31)) {

+    return Data;

+  }

+

+  do {

+    TopBit <<= 1;

+    Data |= TopBit;

+  } while ((TopBit & BIT31) != BIT31);

+

+  return Data;

+}

+

+//

+// Some instructions specify the PC is always considered aligned

+// The PC is after the instruction that is excuting. So you pass

+// in the instruction address and you get back the aligned answer

+//

+UINT32

+PCAlign4 (

+  IN  UINT32  Data

+  )

+{

+  return (Data + 4) & 0xfffffffc;

+}

+

+/**

+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to

+  point to next instructin.

+

+  We cheat and only decode instructions that access

+  memory. If the instruction is not found we dump the instruction in hex.

+

+  @param  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.

+  @param  Buf           Buffer to sprintf disassembly into.

+  @param  Size          Size of Buf in bytes.

+  @param  Extended    TRUE dump hex for instruction too.

+

+**/

+VOID

+DisassembleThumbInstruction (

+  IN  UINT16    **OpCodePtrPtr,

+  OUT CHAR8     *Buf,

+  OUT UINTN     Size,

+  OUT UINT32    *ItBlock,

+  IN  BOOLEAN   Extended

+  )

+{

+  UINT16  *OpCodePtr;

+  UINT16  OpCode;

+  UINT32  OpCode32;

+  UINT32  Index;

+  UINT32  Offset;

+  UINT16  Rd, Rn, Rm, Rt, Rt2;

+  BOOLEAN H1, H2, imod;

+  //BOOLEAN ItFlag;

+  UINT32  PC, Target, msbit, lsbit;

+  CHAR8   *Cond;

+  BOOLEAN S, J1, J2, P, U, W;

+  UINT32  coproc, opc1, opc2, CRd, CRn, CRm;

+  UINT32  Mask;

+

+  OpCodePtr = *OpCodePtrPtr;

+  OpCode = **OpCodePtrPtr;

+

+  // Thumb2 is a stream of 16-bit instructions not a 32-bit instruction.

+  OpCode32 = (((UINT32)OpCode) << 16) | *(OpCodePtr + 1);

+

+  // These register names match branch form, but not others

+  Rd = OpCode & 0x7;

+  Rn = (OpCode >> 3) & 0x7;

+  Rm = (OpCode >> 6) & 0x7;

+  H1 = (OpCode & BIT7) != 0;

+  H2 = (OpCode & BIT6) != 0;

+  imod = (OpCode & BIT4) != 0;

+  PC = (UINT32)(UINTN)OpCodePtr;

+

+  // Increment by the minimum instruction size, Thumb2 could be bigger

+  *OpCodePtrPtr += 1;

+

+  // Manage IT Block ItFlag TRUE means we are in an IT block

+  /*if (*ItBlock != 0) {

+    ItFlag = TRUE;

+    *ItBlock -= 1;

+  } else {

+    ItFlag = FALSE;

+  }*/

+

+  for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {

+    if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {

+      if (Extended) {

+        Offset = AsciiSPrint (Buf, Size, "0x%04x       %-6a", OpCode, gOpThumb[Index].Start);

+      } else {

+        Offset = AsciiSPrint (Buf, Size, "%-6a", gOpThumb[Index].Start);

+      }

+      switch (gOpThumb[Index].AddressMode) {

+      case LOAD_STORE_FORMAT1:

+        // A6.5.1  <Rd>, [<Rn>, #<5_bit_offset>]

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 4) & 0x7c);

+        return;

+      case LOAD_STORE_FORMAT1_H:

+        // A6.5.1  <Rd>, [<Rn>, #<5_bit_offset>]

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 5) & 0x3e);

+        return;

+      case LOAD_STORE_FORMAT1_B:

+        // A6.5.1  <Rd>, [<Rn>, #<5_bit_offset>]

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 6) & 0x1f);

+        return;

+

+      case LOAD_STORE_FORMAT2:

+        // A6.5.1  <Rd>, [<Rn>, <Rm>]

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, Rn, Rm);

+        return;

+      case LOAD_STORE_FORMAT3:

+        // A6.5.1 <Rd>, [PC, #<8_bit_offset>]

+        Target = (OpCode & 0xff) << 2;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x] ;0x%08x", (OpCode >> 8) & 7, Target, PCAlign4 (PC) + Target);

+        return;

+      case LOAD_STORE_FORMAT4:

+        // Rt, [SP, #imm8]

+        Target = (OpCode & 0xff) << 2;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, Target);

+        return;

+

+      case LOAD_STORE_MULTIPLE_FORMAT1:

+        // <Rn>!, {r0-r7}

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode & 0xff));

+        return;

+

+      case POP_FORMAT:

+        // POP {r0-r7,pc}

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT15 : 0)));

+        return;

+

+      case PUSH_FORMAT:

+        // PUSH {r0-r7,lr}

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT14 : 0)));

+        return;

+

+

+      case IMMED_8:

+        // A6.7 <immed_8>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff);

+        return;

+

+      case CONDITIONAL_BRANCH:

+        // A6.3.1 B<cond> <target_address>

+        // Patch in the condition code. A little hack but based on "%-6a"

+        Cond = gCondition[(OpCode >> 8) & 0xf];

+        Buf[Offset-5] = *Cond++;

+        Buf[Offset-4] = *Cond;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x",  PC + 4 + SignExtend32 ((OpCode & 0xff) << 1, BIT8));

+        return;

+      case UNCONDITIONAL_BRANCH_SHORT:

+        // A6.3.2 B  <target_address>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0x3ff) << 1, BIT11));

+        return;

+

+      case BRANCH_EXCHANGE:

+        // A6.3.3 BX|BLX <Rm>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[Rn | (H2 ? 8:0)]);

+        return;

+

+      case DATA_FORMAT1:

+        // A6.4.3  <Rd>, <Rn>, <Rm>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm);

+        return;

+      case DATA_FORMAT2:

+        // A6.4.3  <Rd>, <Rn>, #3_bit_immed

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm);

+        return;

+      case DATA_FORMAT3:

+        // A6.4.3  <Rd>|<Rn>, #imm8

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, #0x%x", (OpCode >> 8) & 7, OpCode & 0xff);

+        return;

+      case DATA_FORMAT4:

+        // A6.4.3  <Rd>|<Rm>, #immed_5

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f);

+        return;

+      case DATA_FORMAT5:

+        // A6.4.3  <Rd>|<Rm>, <Rm>|<Rs>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn);

+        return;

+      case DATA_FORMAT6_SP:

+        // A6.4.3  <Rd>, <reg>, #<8_Bit_immed>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2);

+        return;

+      case DATA_FORMAT6_PC:

+        // A6.4.3  <Rd>, <reg>, #<8_Bit_immed>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2);

+        return;

+      case DATA_FORMAT7:

+        // A6.4.3  SP, SP, #<7_Bit_immed>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp, 0x%x", (OpCode & 0x7f)*4);

+        return;

+      case DATA_FORMAT8:

+        // A6.4.3  <Rd>|<Rn>, <Rm>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]);

+        return;

+

+      case CPS_FORMAT:

+        // A7.1.24

+        AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a",  ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f");

+        return;

+

+      case ENDIAN_FORMAT:

+        // A7.1.24

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE");

+        return;

+

+      case DATA_CBZ:

+        // CB{N}Z <Rn>, <Lable>

+        Target = ((OpCode >> 2) & 0x3e) | (((OpCode & BIT9) == BIT9) ? BIT6 : 0);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[Rd], PC + 4 + Target);

+        return;

+

+      case ADR_FORMAT:

+        // ADR <Rd>, <Label>

+        Target = (OpCode & 0xff) << 2;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[(OpCode >> 8) & 7], PCAlign4 (PC) + Target);

+        return;

+

+      case IT_BLOCK:

+        // ITSTATE = cond:mask   OpCode[7:4]:OpCode[3:0]

+        // ITSTATE[7:5] == cond[3:1]

+        // ITSTATE[4] == 1st Instruction cond[0]

+        // ITSTATE[3] == 2st Instruction cond[0]

+        // ITSTATE[2] == 3st Instruction cond[0]

+        // ITSTATE[1] == 4st Instruction cond[0]

+        // ITSTATE[0] == 1 4 instruction IT block. 0 means 0,1,2 or 3 instructions

+        // 1st one  in ITSTATE low bits defines the number of instructions

+        Mask = (OpCode & 0xf);

+        if ((Mask & 0x1) == 0x1) {

+          *ItBlock = 4;

+          Offset +=  AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E", (Mask & BIT1)?"T":"E");

+        } else if ((OpCode & 0x3) == 0x2) {

+          *ItBlock = 3;

+          Offset +=  AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E");

+        } else if ((OpCode & 0x7) == 0x4) {

+          *ItBlock = 2;

+          Offset +=  AsciiSPrint (&Buf[Offset], Size - Offset, "%a", (Mask & BIT3)?"T":"E");

+        } else if ((OpCode & 0xf) == 0x8) {

+          *ItBlock = 1;

+        }

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gCondition[(OpCode >> 4) & 0xf]);

+        return;

+      }

+    }

+  }

+

+

+  // Thumb2 are 32-bit instructions

+  *OpCodePtrPtr += 1;

+  Rt  = (OpCode32 >> 12) & 0xf;

+  Rt2 = (OpCode32 >> 8) & 0xf;

+  Rd  = (OpCode32 >> 8) & 0xf;

+  Rm  = (OpCode32 & 0xf);

+  Rn  = (OpCode32 >> 16) & 0xf;

+  for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {

+    if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {

+      if (Extended) {

+        Offset = AsciiSPrint (Buf, Size, "0x%04x   %-6a", OpCode32, gOpThumb2[Index].Start);

+      } else {

+        Offset = AsciiSPrint (Buf, Size, "   %-6a", gOpThumb2[Index].Start);

+      }

+      switch (gOpThumb2[Index].AddressMode) {

+      case B_T3:

+        Cond = gCondition[(OpCode32 >> 22) & 0xf];

+        Buf[Offset-5] = *Cond++;

+        Buf[Offset-4] = *Cond;

+        // S:J2:J1:imm6:imm11:0

+        Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3f000);

+        Target |= ((OpCode32 & BIT11) == BIT11)? BIT19 : 0;  // J2

+        Target |= ((OpCode32 & BIT13) == BIT13)? BIT18 : 0;  // J1

+        Target |= ((OpCode32 & BIT26) == BIT26)? BIT20 : 0;  // S

+        Target = SignExtend32 (Target, BIT20);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target);

+        return;

+      case B_T4:

+        // S:I1:I2:imm10:imm11:0

+        Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3ff000);

+        S  = (OpCode32 & BIT26) == BIT26;

+        J1 = (OpCode32 & BIT13) == BIT13;

+        J2 = (OpCode32 & BIT11) == BIT11;

+        Target |= (!(J2 ^ S) ? BIT22 : 0);  // I2

+        Target |= (!(J1 ^ S) ? BIT23 : 0);  // I1

+        Target |= (S ? BIT24 : 0);  // S

+        Target = SignExtend32 (Target, BIT24);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target);

+        return;

+

+      case BL_T2:

+        // BLX  S:I1:I2:imm10:imm11:0

+        Target = ((OpCode32 << 1) & 0xffc) + ((OpCode32 >> 4) & 0x3ff000);

+        S  = (OpCode32 & BIT26) == BIT26;

+        J1 = (OpCode32 & BIT13) == BIT13;

+        J2 = (OpCode32 & BIT11) == BIT11;

+        Target |= (!(J2 ^ S) ? BIT23 : 0);  // I2

+        Target |= (!(J1 ^ S) ? BIT24 : 0);  // I1

+        Target |= (S ? BIT25 : 0);  // S

+        Target = SignExtend32 (Target, BIT25);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PCAlign4 (PC) + Target);

+        return;

+

+      case POP_T2:

+        // <reglist>  some must be zero, handled in table

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList (OpCode32 & 0xffff));

+        return;

+

+      case POP_T3:

+        // <register>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[(OpCode32 >> 12) & 0xf]);

+        return;

+

+      case STM_FORMAT:

+        // <Rn>{!}, <registers>

+        W = (OpCode32 & BIT21) == BIT21;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, %a", gReg[(OpCode32 >> 16) & 0xf], W ? "!":"", ThumbMRegList (OpCode32 & 0xffff));

+        return;

+

+      case LDM_REG_IMM12_SIGNED:

+        // <rt>, <label>

+        Target = OpCode32 & 0xfff;

+        if ((OpCode32 & BIT23) == 0) {

+          // U == 0 means subtrack, U == 1 means add

+          Target = -Target;

+        }

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[(OpCode32 >> 12) & 0xf], PCAlign4 (PC) + Target);

+        return;

+

+      case LDM_REG_INDIRECT_LSL:

+        // <rt>, [<rn>, <rm> {, LSL #<imm2>]}

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a, %a", gReg[Rt], gReg[Rn], gReg[Rm]);

+        if (((OpCode32 >> 4) & 3) == 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, "]");

+        } else {

+          AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL #%d]", (OpCode32 >> 4) & 3);

+        }

+        return;

+

+      case LDM_REG_IMM12:

+        // <rt>, [<rn>, {, #<imm12>]}

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]);

+        if ((OpCode32 & 0xfff) == 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, "]");

+        } else {

+          AsciiSPrint (&Buf[Offset], Size - Offset, ", #0x%x]", OpCode32 & 0xfff);

+        }

+        return;

+

+      case LDM_REG_IMM8:

+        // <rt>, [<rn>, {, #<imm8>}]{!}

+        W = (OpCode32 & BIT8) == BIT8;

+        U = (OpCode32 & BIT9) == BIT9;

+        P = (OpCode32 & BIT10) == BIT10;

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]);

+        if (P) {

+          if ((OpCode32 & 0xff) == 0) {

+            AsciiSPrint (&Buf[Offset], Size - Offset, "]%a", W?"!":"");

+          } else {

+            AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-" , OpCode32 & 0xff, W?"!":"");

+          }

+        } else {

+          AsciiSPrint (&Buf[Offset], Size - Offset, "], #%a0x%x", U?"":"-", OpCode32 & 0xff);

+        }

+        return;

+

+      case LDRD_REG_IMM8_SIGNED:

+        // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}

+        P = (OpCode32 & BIT24) == BIT24;  // index = P

+        U = (OpCode32 & BIT23) == BIT23;

+        W = (OpCode32 & BIT21) == BIT21;

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, [%a", gReg[Rt], gReg[Rt2], gReg[Rn]);

+        if (P) {

+          if ((OpCode32 & 0xff) == 0) {

+            AsciiSPrint (&Buf[Offset], Size - Offset, "]");

+          } else {

+            AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-", (OpCode32 & 0xff) << 2, W?"!":"");

+          }

+        } else {

+          if ((OpCode32 & 0xff) != 0) {

+            AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x", U?"":"-", (OpCode32 & 0xff) << 2);

+          }

+        }

+        return;

+

+      case LDRD_REG_IMM8:

+        // LDRD <rt>, <rt2>, <label>

+        Target = (OpCode32 & 0xff) << 2;

+        if ((OpCode32 & BIT23) == 0) {

+          // U == 0 means subtrack, U == 1 means add

+          Target = -Target;

+        }

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rt], gReg[Rt2], PC + 4 + Target);

+        return;

+

+      case LDREXB:

+        // LDREXB <Rt>, [Rn]

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a]", gReg[Rt], gReg[Rn]);

+        return;

+

+      case LDREXD:

+        // LDREXD <Rt>, <Rt2>, [<Rn>]

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a, [%a]", gReg[Rt], gReg[Rt2], gReg[Rn]);

+        return;

+

+      case SRS_FORMAT:

+        // SP{!}, #<mode>

+        W = (OpCode32 & BIT21) == BIT21;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " SP%a, #0x%x", W?"!":"", OpCode32 & 0x1f);

+        return;

+

+      case RFE_FORMAT:

+        // <Rn>{!}

+        W = (OpCode32 & BIT21) == BIT21;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, #0x%x", gReg[Rn], W?"!":"");

+        return;

+

+      case ADD_IMM12:

+        // ADD{S} <Rd>, <Rn>, #<const>   i:imm3:imm8

+        if ((OpCode32 & BIT20) == BIT20) {

+          Buf[Offset - 3] = 'S';  // assume %-6a

+        }

+        Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #0x%x", gReg[Rd], gReg[Rn], Target);

+        return;

+

+      case ADD_IMM12_1REG:

+        // MOV{S} <Rd>, #<const>   i:imm3:imm8

+        if ((OpCode32 & BIT20) == BIT20) {

+          Buf[Offset - 3] = 'S';  // assume %-6a

+        }

+        Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target);

+        return;

+

+      case THUMB2_IMM16:

+        // MOVW <Rd>, #<const>   i:imm3:imm8

+        Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);

+        Target |= ((OpCode32 >> 4) & 0xf0000);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target);

+        return;

+

+      case ADD_IMM5:

+        // ADC{S}  <Rd>, <Rn>, <Rm> {,LSL #<const>} imm3:imm2

+        if ((OpCode32 & BIT20) == BIT20) {

+          Buf[Offset - 3] = 'S';  // assume %-6a

+        }

+        Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm]);

+        if (Target != 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target);

+        }

+        return;

+

+      case ADD_IMM5_2REG:

+        // CMP  <Rn>, <Rm> {,LSL #<const>} imm3:imm2

+        Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rn], gReg[Rm]);

+        if (Target != 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target);

+        }

+

+

+      case ASR_IMM5:

+        // ARS  <Rd>, <Rm> #<const>} imm3:imm2

+        if ((OpCode32 & BIT20) == BIT20) {

+          Buf[Offset - 3] = 'S';  // assume %-6a

+        }

+        Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a #%d", gReg[Rd], gReg[Rm], Target);

+        return;

+

+      case ASR_3REG:

+        // ARS  <Rd>, <Rn>, <Rm>

+        if ((OpCode32 & BIT20) == BIT20) {

+          Buf[Offset - 3] = 'S';  // assume %-6a

+        }

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a %a", gReg[Rd], gReg[Rn], gReg[Rm]);

+        return;

+

+      case ADR_THUMB2:

+        // ADDR <Rd>, <label>

+        Target = (OpCode32 & 0xff) | ((OpCode32 >> 8) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);

+        if ((OpCode & (BIT23 | BIT21)) == (BIT23 | BIT21)) {

+          Target = PCAlign4 (PC) - Target;

+        } else {

+          Target = PCAlign4 (PC) + Target;

+        }

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, 0x%08x", gReg[Rd], Target);

+        return;

+

+      case CMN_THUMB2:

+        // CMN <Rn>, #<const>}

+        Target = (OpCode32 & 0xff) | ((OpCode >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rn], Target);

+        return;

+

+      case BFC_THUMB2:

+        // BFI <Rd>, <Rn>, #<lsb>, #<width>

+        msbit = OpCode32 & 0x1f;

+        lsbit = ((OpCode32 >> 6) & 3) | ((OpCode >> 10) &  0x1c);

+        if ((Rn == 0xf) & (AsciiStrCmp (gOpThumb2[Index].Start, "BFC") == 0)){

+          // BFC <Rd>, #<lsb>, #<width>

+          AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #%d, #%d", gReg[Rd], lsbit, msbit - lsbit + 1);

+        } else if (AsciiStrCmp (gOpThumb2[Index].Start, "BFI") == 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit - lsbit + 1);

+        } else {

+          AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit + 1);

+        }

+        return;

+

+      case CPD_THUMB2:

+        // <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>

+        coproc = (OpCode32 >> 8)  & 0xf;

+        opc1   = (OpCode32 >> 20) & 0xf;

+        opc2   = (OpCode32 >> 5)  & 0x7;

+        CRd    = (OpCode32 >> 12) & 0xf;

+        CRn    = (OpCode32 >> 16) & 0xf;

+        CRm    = OpCode32 & 0xf;

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,c%d,c%d,c%d", coproc, opc1, CRd, CRn, CRm);

+        if (opc2 != 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);

+        }

+        return;

+

+      case MRC_THUMB2:

+        // MRC  <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>

+        coproc = (OpCode32 >> 8)  & 0xf;

+        opc1   = (OpCode32 >> 20) & 0xf;

+        opc2   = (OpCode32 >> 5)  & 0x7;

+        CRn    = (OpCode32 >> 16) & 0xf;

+        CRm    = OpCode32 & 0xf;

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,c%d,c%d", coproc, opc1, gReg[Rt], CRn, CRm);

+        if (opc2 != 0) {

+          AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);

+        }

+        return;

+

+      case MRRC_THUMB2:

+        // MRC  <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>,<opc2>

+        coproc = (OpCode32 >> 8)  & 0xf;

+        opc1   = (OpCode32 >> 20) & 0xf;

+        CRn    = (OpCode32 >> 16) & 0xf;

+        CRm    = OpCode32 & 0xf;

+        Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,%a,c%d", coproc, opc1, gReg[Rt], gReg[Rt2], CRm);

+        return;

+

+      case THUMB2_2REGS:

+        // <Rd>, <Rm>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd], gReg[Rm]);

+        return;

+

+      case THUMB2_4REGS:

+        // <Rd>, <Rn>, <Rm>, <Ra>

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm], gReg[Rt]);

+        return;

+

+      case THUMB2_MRS:

+        // MRS <Rd>, CPSR

+        AsciiSPrint (&Buf[Offset], Size - Offset, " %a, CPSR", gReg[Rd]);

+        return;

+

+      case THUMB2_MSR:

+        // MRS CPSR_<fields>, <Rd>

+        Target = (OpCode32 >> 10) & 3;

+        AsciiSPrint (&Buf[Offset], Size - Offset, " CPSR_%a%a, %a", (Target & 2) == 0 ? "":"f", (Target & 1) == 0 ? "":"s", gReg[Rd]);

+        return;

+

+      case THUMB2_NO_ARGS:

+      default:

+        break;

+      }

+    }

+  }

+

+  AsciiSPrint (Buf, Size, "0x%08x", OpCode32);

+}

+

+

+

+VOID

+DisassembleArmInstruction (

+  IN  UINT32    **OpCodePtr,

+  OUT CHAR8     *Buf,

+  OUT UINTN     Size,

+  IN  BOOLEAN   Extended

+  );

+

+

+/**

+  Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to

+  point to next instructin.

+

+  We cheat and only decode instructions that access

+  memory. If the instruction is not found we dump the instruction in hex.

+

+  @param  OpCodePtrPtr  Pointer to pointer of ARM Thumb instruction to disassemble.

+  @param  Thumb         TRUE for Thumb(2), FALSE for ARM instruction stream

+  @param  Extended      TRUE dump hex for instruction too.

+  @param  ItBlock       Size of IT Block

+  @param  Buf           Buffer to sprintf disassembly into.

+  @param  Size          Size of Buf in bytes.

+

+**/

+VOID

+DisassembleInstruction (

+  IN  UINT8     **OpCodePtr,

+  IN  BOOLEAN   Thumb,

+  IN  BOOLEAN   Extended,

+  IN OUT UINT32 *ItBlock,

+  OUT CHAR8     *Buf,

+  OUT UINTN     Size

+  )

+{

+  if (Thumb) {

+    DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, ItBlock, Extended);

+  } else {

+    DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size, Extended);

+  }

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c
new file mode 100755
index 0000000..12b1940
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c
@@ -0,0 +1,284 @@
+/** @file

+  Generic ARM implementation of DmaLib.h

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <PiDxe.h>

+#include <Library/DebugLib.h>

+#include <Library/DmaLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UncachedMemoryAllocationLib.h>

+#include <Library/IoLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/ArmLib.h>

+

+#include <Protocol/Cpu.h>

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS      HostAddress;

+  EFI_PHYSICAL_ADDRESS      DeviceAddress;

+  UINTN                     NumberOfBytes;

+  DMA_MAP_OPERATION         Operation;

+  BOOLEAN                   DoubleBuffer;

+} MAP_INFO_INSTANCE;

+

+

+

+EFI_CPU_ARCH_PROTOCOL      *gCpu;

+UINTN                      gCacheAlignment = 0;

+

+/**

+  Provides the DMA controller-specific addresses needed to access system memory.

+

+  Operation is relative to the DMA bus master.

+

+  @param  Operation             Indicates if the bus master is going to read or write to system memory.

+  @param  HostAddress           The system memory address to map to the DMA controller.

+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes

+                                that were mapped.

+  @param  DeviceAddress         The resulting map address for the bus master controller to use to

+                                access the hosts HostAddress.

+  @param  Mapping               A resulting value to pass to Unmap().

+

+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.

+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.

+

+**/

+EFI_STATUS

+EFIAPI

+DmaMap (

+  IN     DMA_MAP_OPERATION              Operation,

+  IN     VOID                           *HostAddress,

+  IN OUT UINTN                          *NumberOfBytes,

+  OUT    PHYSICAL_ADDRESS               *DeviceAddress,

+  OUT    VOID                           **Mapping

+  )

+{

+  EFI_STATUS                      Status;

+  MAP_INFO_INSTANCE               *Map;

+  VOID                            *Buffer;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;

+

+  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL ) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Operation >= MapOperationMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *DeviceAddress = ConvertToPhysicalAddress (HostAddress);

+

+  // Remember range so we can flush on the other side

+  Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));

+  if (Map == NULL) {

+    return  EFI_OUT_OF_RESOURCES;

+  }

+

+  *Mapping = Map;

+

+  if ((((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) ||

+      ((*NumberOfBytes % gCacheAlignment) != 0)) {

+

+    // Get the cacheability of the region

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

+    if (EFI_ERROR(Status)) {

+      return Status;

+    }

+

+    // If the mapped buffer is not an uncached buffer

+    if ( (GcdDescriptor.Attributes != EFI_MEMORY_WC) &&

+         (GcdDescriptor.Attributes != EFI_MEMORY_UC) )

+    {

+      //

+      // If the buffer does not fill entire cache lines we must double buffer into

+      // uncached memory. Device (PCI) address becomes uncached page.

+      //

+      Map->DoubleBuffer  = TRUE;

+      Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {

+        CopyMem (Buffer, HostAddress, *NumberOfBytes);

+      }

+

+      *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;

+    } else {

+      Map->DoubleBuffer  = FALSE;

+    }

+  } else {

+    Map->DoubleBuffer  = FALSE;

+

+    // Flush the Data Cache (should not have any effect if the memory region is uncached)

+    gCpu->FlushDataCache (gCpu, *DeviceAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);

+

+    if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {

+      // In case the buffer is used for instance to send command to a PCI controller, we must ensure the memory is uncached

+      Status = gDS->SetMemorySpaceAttributes (*DeviceAddress & ~(BASE_4KB - 1), ALIGN_VALUE (*NumberOfBytes, BASE_4KB), EFI_MEMORY_WC);

+      ASSERT_EFI_ERROR (Status);

+    }

+  }

+

+  Map->HostAddress   = (UINTN)HostAddress;

+  Map->DeviceAddress = *DeviceAddress;

+  Map->NumberOfBytes = *NumberOfBytes;

+  Map->Operation     = Operation;

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or DmaMapBusMasterCommonBuffer()

+  operation and releases any corresponding resources.

+

+  @param  Mapping               The mapping value returned from DmaMap*().

+

+  @retval EFI_SUCCESS           The range was unmapped.

+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.

+

+**/

+EFI_STATUS

+EFIAPI

+DmaUnmap (

+  IN  VOID                         *Mapping

+  )

+{

+  MAP_INFO_INSTANCE *Map;

+

+  if (Mapping == NULL) {

+    ASSERT (FALSE);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Map = (MAP_INFO_INSTANCE *)Mapping;

+

+  if (Map->DoubleBuffer) {

+    if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) {

+      CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);

+    }

+

+    DmaFreeBuffer (EFI_SIZE_TO_PAGES (Map->NumberOfBytes), (VOID *)(UINTN)Map->DeviceAddress);

+

+  } else {

+    if (Map->Operation == MapOperationBusMasterWrite) {

+      //

+      // Make sure we read buffer from uncached memory and not the cache

+      //

+      gCpu->FlushDataCache (gCpu, Map->HostAddress, Map->NumberOfBytes, EfiCpuFlushTypeInvalidate);

+    }

+  }

+

+  FreePool (Map);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.

+  mapping.

+

+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or

+                                EfiRuntimeServicesData.

+  @param  Pages                 The number of pages to allocate.

+  @param  HostAddress           A pointer to store the base system memory address of the

+                                allocated range.

+

+                                @retval EFI_SUCCESS           The requested memory pages were allocated.

+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are

+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.

+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.

+

+**/

+EFI_STATUS

+EFIAPI

+DmaAllocateBuffer (

+  IN  EFI_MEMORY_TYPE              MemoryType,

+  IN  UINTN                        Pages,

+  OUT VOID                         **HostAddress

+  )

+{

+  if (HostAddress == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData

+  //

+  // We used uncached memory to keep coherency

+  //

+  if (MemoryType == EfiBootServicesData) {

+    *HostAddress = UncachedAllocatePages (Pages);

+  } else if (MemoryType == EfiRuntimeServicesData) {

+    *HostAddress = UncachedAllocateRuntimePages (Pages);

+  } else {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Frees memory that was allocated with DmaAllocateBuffer().

+

+  @param  Pages                 The number of pages to free.

+  @param  HostAddress           The base system memory address of the allocated range.

+

+  @retval EFI_SUCCESS           The requested memory pages were freed.

+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages

+                                was not allocated with DmaAllocateBuffer().

+

+**/

+EFI_STATUS

+EFIAPI

+DmaFreeBuffer (

+  IN  UINTN                        Pages,

+  IN  VOID                         *HostAddress

+  )

+{

+  if (HostAddress == NULL) {

+     return EFI_INVALID_PARAMETER;

+  }

+

+  UncachedFreePages (HostAddress, Pages);

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+ArmDmaLibConstructor (

+  IN EFI_HANDLE       ImageHandle,

+  IN EFI_SYSTEM_TABLE *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+

+  // Get the Cpu protocol for later use

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);

+  ASSERT_EFI_ERROR(Status);

+

+  gCacheAlignment = ArmDataCacheLineLength ();

+

+  return Status;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
new file mode 100755
index 0000000..20228d2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
@@ -0,0 +1,50 @@
+#/** @file

+#

+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmDmaLib

+  FILE_GUID                      = F1BD6B36-B705-43aa-8A28-33F58ED85EFB

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DmaLib

+  CONSTRUCTOR                    = ArmDmaLibConstructor

+

+[Sources.common]

+  ArmDmaLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+  UefiBootServicesTableLib

+  MemoryAllocationLib

+  UncachedMemoryAllocationLib

+  IoLib

+  BaseMemoryLib

+  ArmLib

+

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[Guids]

+

+[Pcd]

+

+[Depex]

+  gEfiCpuArchProtocolGuid

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.c
new file mode 100644
index 0000000..826827f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.c
@@ -0,0 +1,139 @@
+/** @file

+

+  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>

+  Copyright (c) 2014, 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 <Library/ArmGenericTimerCounterLib.h>

+#include <Library/ArmArchTimer.h>

+

+VOID

+EFIAPI

+ArmGenericTimerEnableTimer (

+  VOID

+  )

+{

+  UINTN TimerCtrlReg;

+

+  ArmArchTimerReadReg (CntpCtl, (VOID *)&TimerCtrlReg);

+  TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE;

+  ArmArchTimerWriteReg (CntpCtl, (VOID *)&TimerCtrlReg);

+}

+

+VOID

+EFIAPI

+ArmGenericTimerDisableTimer (

+  VOID

+  )

+{

+  UINTN TimerCtrlReg;

+

+  ArmArchTimerReadReg (CntpCtl, (VOID *)&TimerCtrlReg);

+  TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;

+  ArmArchTimerWriteReg (CntpCtl, (VOID *)&TimerCtrlReg);

+}

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerFreq (

+  IN   UINTN  FreqInHz

+  )

+{

+  ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz);

+}

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerFreq (

+  VOID

+  )

+{

+  UINTN ArchTimerFreq = 0;

+  ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq);

+  return ArchTimerFreq;

+}

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerVal (

+  VOID

+  )

+{

+  UINTN ArchTimerValue;

+  ArmArchTimerReadReg (CntpTval, (VOID *)&ArchTimerValue);

+

+  return ArchTimerValue;

+}

+

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerVal (

+  IN   UINTN   Value

+  )

+{

+  ArmArchTimerWriteReg (CntpTval, (VOID *)&Value);

+}

+

+UINT64

+EFIAPI

+ArmGenericTimerGetSystemCount (

+  VOID

+  )

+{

+  UINT64 SystemCount;

+  ArmArchTimerReadReg (CntPct, (VOID *)&SystemCount);

+

+  return SystemCount;

+}

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerCtrlReg (

+  VOID

+  )

+{

+  UINTN  Value;

+  ArmArchTimerReadReg (CntpCtl, (VOID *)&Value);

+

+  return Value;

+}

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerCtrlReg (

+  UINTN Value

+  )

+{

+  ArmArchTimerWriteReg (CntpCtl, (VOID *)&Value);

+}

+

+UINT64

+EFIAPI

+ArmGenericTimerGetCompareVal (

+  VOID

+  )

+{

+  UINT64  Value;

+  ArmArchTimerReadReg (CntpCval, (VOID *)&Value);

+

+  return Value;

+}

+

+VOID

+EFIAPI

+ArmGenericTimerSetCompareVal (

+  IN   UINT64   Value

+  )

+{

+  ArmArchTimerWriteReg (CntpCval, (VOID *)&Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
new file mode 100644
index 0000000..5420608
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
@@ -0,0 +1,33 @@
+#/** @file

+#  Implement ArmGenericTimerCounterLib using the physical timer

+#

+#  Copyright (c) 2014, 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                      = ArmGenericTimerPhyCounterLib

+  FILE_GUID                      = 7A07E61D-9967-407F-AE85-2EB0B50BEF2C

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmGenericTimerCounterLib

+

+[Sources]

+  ArmGenericTimerPhyCounterLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  BaseLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c
new file mode 100644
index 0000000..f99c852
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c
@@ -0,0 +1,149 @@
+/** @file

+

+  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>

+  Copyright (c) 2014, 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 <Library/ArmGenericTimerCounterLib.h>

+#include <Library/ArmArchTimer.h>

+

+VOID

+EFIAPI

+ArmGenericTimerEnableTimer (

+  VOID

+  )

+{

+  UINTN TimerCtrlReg;

+

+  ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg);

+  TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE;

+

+  //

+  // When running under KVM, we need to unmask the interrupt on the timer side

+  // as KVM will mask it when servicing the interrupt at the hypervisor level

+  // and delivering the virtual timer interrupt to the guest. Otherwise, the

+  // interrupt will fire again, trapping into the hypervisor again, etc. etc.

+  // This is scheduled to be fixed on the KVM side, but there is no harm in

+  // leaving this in once KVM gets fixed.

+  //

+  TimerCtrlReg &= ~ARM_ARCH_TIMER_IMASK;

+  ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg);

+}

+

+VOID

+EFIAPI

+ArmGenericTimerDisableTimer (

+  VOID

+  )

+{

+  UINTN TimerCtrlReg;

+

+  ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg);

+  TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;

+  ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg);

+}

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerFreq (

+  IN   UINTN  FreqInHz

+  )

+{

+  ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz);

+}

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerFreq (

+  VOID

+  )

+{

+  UINTN ArchTimerFreq = 0;

+  ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq);

+  return ArchTimerFreq;

+}

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerVal (

+  VOID

+  )

+{

+  UINTN ArchTimerValue;

+  ArmArchTimerReadReg (CntvTval, (VOID *)&ArchTimerValue);

+

+  return ArchTimerValue;

+}

+

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerVal (

+  IN   UINTN   Value

+  )

+{

+  ArmArchTimerWriteReg (CntvTval, (VOID *)&Value);

+}

+

+UINT64

+EFIAPI

+ArmGenericTimerGetSystemCount (

+  VOID

+  )

+{

+  UINT64 SystemCount;

+  ArmArchTimerReadReg (CntvCt, (VOID *)&SystemCount);

+

+  return SystemCount;

+}

+

+UINTN

+EFIAPI

+ArmGenericTimerGetTimerCtrlReg (

+  VOID

+  )

+{

+  UINTN  Value;

+  ArmArchTimerReadReg (CntvCtl, (VOID *)&Value);

+

+  return Value;

+}

+

+VOID

+EFIAPI

+ArmGenericTimerSetTimerCtrlReg (

+  UINTN Value

+  )

+{

+  ArmArchTimerWriteReg (CntvCtl, (VOID *)&Value);

+}

+

+UINT64

+EFIAPI

+ArmGenericTimerGetCompareVal (

+  VOID

+  )

+{

+  UINT64  Value;

+  ArmArchTimerReadReg (CntvCval, (VOID *)&Value);

+

+  return Value;

+}

+

+VOID

+EFIAPI

+ArmGenericTimerSetCompareVal (

+  IN   UINT64   Value

+  )

+{

+  ArmArchTimerWriteReg (CntvCval, (VOID *)&Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
new file mode 100644
index 0000000..9267dc3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
@@ -0,0 +1,33 @@
+#/** @file

+#  Implement ArmGenericTimerCounterLib using the virtual timer

+#

+#  Copyright (c) 2014, 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                      = ArmGenericTimerVirtCounterLib

+  FILE_GUID                      = 3C0D77CC-4F27-49C8-B25C-2D01D81ED4D8

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmGenericTimerCounterLib

+

+[Sources]

+  ArmGenericTimerVirtCounterLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  BaseLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
new file mode 100644
index 0000000..99a1d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
@@ -0,0 +1,42 @@
+//

+//  Copyright (c) 2012-2014, 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.

+//

+//

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(ArmCallHvc)

+

+ASM_PFX(ArmCallHvc):

+  // Push x0 on the stack - The stack must always be quad-word aligned

+  str   x0, [sp, #-16]!

+

+  // Load the HVC arguments values into the appropriate registers

+  ldp   x6, x7, [x0, #48]

+  ldp   x4, x5, [x0, #32]

+  ldp   x2, x3, [x0, #16]

+  ldp   x0, x1, [x0, #0]

+

+  hvc   #0

+

+  // Pop the ARM_HVC_ARGS structure address from the stack into x9

+  ldr   x9, [sp], #16

+

+  // Store the HVC returned values into the ARM_HVC_ARGS structure.

+  // A HVC call can return up to 4 values

+  stp   x2, x3, [x9, #16]

+  stp   x0, x1, [x9, #0]

+

+  mov   x0, x9

+

+  ret

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
new file mode 100644
index 0000000..25ceb6a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
@@ -0,0 +1,53 @@
+//

+//  Copyright (c) 2012-2014, 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.

+//

+//

+

+.text

+.align 3

+.arch_extension virt

+

+GCC_ASM_EXPORT(ArmCallHvc)

+

+ASM_PFX(ArmCallHvc):

+    push    {r4-r8}

+    // r0 will be popped just after the HVC call

+    push    {r0}

+

+    // Load the HVC arguments values into the appropriate registers

+    ldr     r7, [r0, #28]

+    ldr     r6, [r0, #24]

+    ldr     r5, [r0, #20]

+    ldr     r4, [r0, #16]

+    ldr     r3, [r0, #12]

+    ldr     r2, [r0, #8]

+    ldr     r1, [r0, #4]

+    ldr     r0, [r0, #0]

+

+    hvc     #0

+

+    // Pop the ARM_HVC_ARGS structure address from the stack into r8

+    pop     {r8}

+

+    // Load the HVC returned values into the appropriate registers

+    // A HVC call can return up to 4 values - we do not need to store back r4-r7.

+    str     r3, [r8, #12]

+    str     r2, [r8, #8]

+    str     r1, [r8, #4]

+    str     r0, [r8, #0]

+

+    mov     r0, r8

+

+    // Restore the registers r4-r8

+    pop     {r4-r8}

+

+    bx      lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm
new file mode 100644
index 0000000..bac26fb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm
@@ -0,0 +1,53 @@
+//

+//  Copyright (c) 2012-2014, 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.

+//

+//

+

+    EXPORT ArmCallHvc

+

+    AREA   ArmHvc, CODE, READONLY

+

+ArmCallHvc

+    push    {r4-r8}

+    // r0 will be popped just after the HVC call

+    push     {r0}

+

+    // Load the HVC arguments values into the appropriate registers

+    ldr     r7, [r0, #28]

+    ldr     r6, [r0, #24]

+    ldr     r5, [r0, #20]

+    ldr     r4, [r0, #16]

+    ldr     r3, [r0, #12]

+    ldr     r2, [r0, #8]

+    ldr     r1, [r0, #4]

+    ldr     r0, [r0, #0]

+

+    hvc     #0

+

+    // Pop the ARM_HVC_ARGS structure address from the stack into r8

+    pop     {r8}

+

+    // Load the HVC returned values into the appropriate registers

+    // A HVC call can return up to 4 values - we do not need to store back r4-r7.

+    str     r3, [r8, #12]

+    str     r2, [r8, #8]

+    str     r1, [r8, #4]

+    str     r0, [r8, #0]

+

+    mov     r0, r8

+

+    // Restore the registers r4-r8

+    pop     {r4-r8}

+

+    bx      lr

+

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
new file mode 100644
index 0000000..92efac5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
@@ -0,0 +1,32 @@
+#/** @file

+#

+#  Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR>

+#  Copyright (c) 2014, 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                      = ArmHvcLib

+  FILE_GUID                      = E594959A-D150-44D3-963B-BA90329D3D9A

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmHvcLib

+

+[Sources.ARM]

+  Arm/ArmHvc.asm    | RVCT

+  Arm/ArmHvc.S      | GCC

+

+[Sources.AARCH64]

+  AArch64/ArmHvc.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimer.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimer.c
new file mode 100644
index 0000000..63ce197
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimer.c
@@ -0,0 +1,168 @@
+/** @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 <Uefi.h>

+#include <Chipset/AArch64.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include "AArch64Lib.h"

+#include "ArmLibPrivate.h"

+#include <Library/ArmArchTimer.h>

+

+VOID

+EFIAPI

+ArmArchTimerReadReg (

+    IN   ARM_ARCH_TIMER_REGS   Reg,

+    OUT  VOID                  *DstBuf

+    )

+{

+  // Check if the Generic/Architecture timer is implemented

+  if (ArmIsArchTimerImplemented ()) {

+

+    switch (Reg) {

+

+    case CntFrq:

+      *((UINTN *)DstBuf) = ArmReadCntFrq ();

+      break;

+

+    case CntPct:

+      *((UINT64 *)DstBuf) = ArmReadCntPct ();

+      break;

+

+    case CntkCtl:

+      *((UINTN *)DstBuf) = ArmReadCntkCtl();

+      break;

+

+    case CntpTval:

+      *((UINTN *)DstBuf) = ArmReadCntpTval ();

+      break;

+

+    case CntpCtl:

+      *((UINTN *)DstBuf) = ArmReadCntpCtl ();

+      break;

+

+    case CntvTval:

+      *((UINTN *)DstBuf) = ArmReadCntvTval ();

+      break;

+

+    case CntvCtl:

+      *((UINTN *)DstBuf) = ArmReadCntvCtl ();

+      break;

+

+    case CntvCt:

+      *((UINT64 *)DstBuf) = ArmReadCntvCt ();

+      break;

+

+    case CntpCval:

+      *((UINT64 *)DstBuf) = ArmReadCntpCval ();

+      break;

+

+    case CntvCval:

+      *((UINT64 *)DstBuf) = ArmReadCntvCval ();

+      break;

+

+    case CntvOff:

+      *((UINT64 *)DstBuf) = ArmReadCntvOff ();

+      break;

+

+    case CnthCtl:

+    case CnthpTval:

+    case CnthpCtl:

+    case CnthpCval:

+    DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));

+      break;

+

+    default:

+      DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));

+    }

+  } else {

+    DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));

+    ASSERT (0);

+  }

+}

+

+VOID

+EFIAPI

+ArmArchTimerWriteReg (

+    IN   ARM_ARCH_TIMER_REGS   Reg,

+    IN   VOID                  *SrcBuf

+    )

+{

+  // Check if the Generic/Architecture timer is implemented

+  if (ArmIsArchTimerImplemented ()) {

+

+    switch (Reg) {

+

+    case CntFrq:

+      ArmWriteCntFrq (*((UINTN *)SrcBuf));

+      break;

+

+    case CntPct:

+      DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTPCT \n"));

+      break;

+

+    case CntkCtl:

+      ArmWriteCntkCtl (*((UINTN *)SrcBuf));

+      break;

+

+    case CntpTval:

+      ArmWriteCntpTval (*((UINTN *)SrcBuf));

+      break;

+

+    case CntpCtl:

+      ArmWriteCntpCtl (*((UINTN *)SrcBuf));

+      break;

+

+    case CntvTval:

+      ArmWriteCntvTval (*((UINTN *)SrcBuf));

+      break;

+

+    case CntvCtl:

+      ArmWriteCntvCtl (*((UINTN *)SrcBuf));

+      break;

+

+    case CntvCt:

+      DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTVCT \n"));

+      break;

+

+    case CntpCval:

+      ArmWriteCntpCval (*((UINT64 *)SrcBuf) );

+      break;

+

+    case CntvCval:

+      ArmWriteCntvCval (*((UINT64 *)SrcBuf) );

+      break;

+

+    case CntvOff:

+      ArmWriteCntvOff (*((UINT64 *)SrcBuf));

+      break;

+

+    case CnthCtl:

+    case CnthpTval:

+    case CnthpCtl:

+    case CnthpCval:

+      DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));

+      break;

+

+    default:

+      DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));

+    }

+  } else {

+    DEBUG ((EFI_D_ERROR, "Attempt to write to ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));

+    ASSERT (0);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
new file mode 100644
index 0000000..1ac0108
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
@@ -0,0 +1,140 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+

+GCC_ASM_EXPORT(ArmReadCntFrq)

+GCC_ASM_EXPORT(ArmWriteCntFrq)

+GCC_ASM_EXPORT(ArmReadCntPct)

+GCC_ASM_EXPORT(ArmReadCntkCtl)

+GCC_ASM_EXPORT(ArmWriteCntkCtl)

+GCC_ASM_EXPORT(ArmReadCntpTval)

+GCC_ASM_EXPORT(ArmWriteCntpTval)

+GCC_ASM_EXPORT(ArmReadCntpCtl)

+GCC_ASM_EXPORT(ArmWriteCntpCtl)

+GCC_ASM_EXPORT(ArmReadCntvTval)

+GCC_ASM_EXPORT(ArmWriteCntvTval)

+GCC_ASM_EXPORT(ArmReadCntvCtl)

+GCC_ASM_EXPORT(ArmWriteCntvCtl)

+GCC_ASM_EXPORT(ArmReadCntvCt)

+GCC_ASM_EXPORT(ArmReadCntpCval)

+GCC_ASM_EXPORT(ArmWriteCntpCval)

+GCC_ASM_EXPORT(ArmReadCntvCval)

+GCC_ASM_EXPORT(ArmWriteCntvCval)

+GCC_ASM_EXPORT(ArmReadCntvOff)

+GCC_ASM_EXPORT(ArmWriteCntvOff)

+

+ASM_PFX(ArmReadCntFrq):

+  mrs   x0, cntfrq_el0           // Read CNTFRQ

+  ret

+

+

+# NOTE - Can only write while at highest implemented EL level (EL3 on model). Else ReadOnly (EL2, EL1, EL0)

+ASM_PFX(ArmWriteCntFrq):

+  msr   cntfrq_el0, x0           // Write to CNTFRQ

+  ret

+

+

+ASM_PFX(ArmReadCntPct):

+  mrs   x0, cntpct_el0           // Read CNTPCT (Physical counter register)

+  ret

+

+

+ASM_PFX(ArmReadCntkCtl):

+  mrs   x0, cntkctl_el1          // Read CNTK_CTL (Timer PL1 Control Register)

+  ret

+

+

+ASM_PFX(ArmWriteCntkCtl):

+  mrs   x0, cntkctl_el1          // Write to CNTK_CTL (Timer PL1 Control Register)

+  ret

+

+

+ASM_PFX(ArmReadCntpTval):

+  mrs   x0, cntp_tval_el0        // Read CNTP_TVAL (PL1 physical timer value register)

+  ret

+

+

+ASM_PFX(ArmWriteCntpTval):

+  msr   cntp_tval_el0, x0        // Write to CNTP_TVAL (PL1 physical timer value register)

+  ret

+

+

+ASM_PFX(ArmReadCntpCtl):

+  mrs   x0, cntp_ctl_el0         // Read CNTP_CTL (PL1 Physical Timer Control Register)

+  ret

+

+

+ASM_PFX(ArmWriteCntpCtl):

+  msr   cntp_ctl_el0, x0         // Write to  CNTP_CTL (PL1 Physical Timer Control Register)

+  ret

+

+

+ASM_PFX(ArmReadCntvTval):

+  mrs   x0, cntv_tval_el0        // Read CNTV_TVAL (Virtual Timer Value register)

+  ret

+

+

+ASM_PFX(ArmWriteCntvTval):

+  msr   cntv_tval_el0, x0        // Write to CNTV_TVAL (Virtual Timer Value register)

+  ret

+

+

+ASM_PFX(ArmReadCntvCtl):

+  mrs   x0, cntv_ctl_el0         // Read CNTV_CTL (Virtual Timer Control Register)

+  ret

+

+

+ASM_PFX(ArmWriteCntvCtl):

+  msr   cntv_ctl_el0, x0         // Write to CNTV_CTL (Virtual Timer Control Register)

+  ret

+

+

+ASM_PFX(ArmReadCntvCt):

+  mrs  x0, cntvct_el0            // Read CNTVCT  (Virtual Count Register)

+  ret

+

+

+ASM_PFX(ArmReadCntpCval):

+  mrs   x0, cntp_cval_el0        // Read CNTP_CTVAL (Physical Timer Compare Value Register)

+  ret

+

+

+ASM_PFX(ArmWriteCntpCval):

+  msr   cntp_cval_el0, x0        // Write to CNTP_CTVAL (Physical Timer Compare Value Register)

+  ret

+

+

+ASM_PFX(ArmReadCntvCval):

+  mrs   x0, cntv_cval_el0        // Read CNTV_CTVAL (Virtual Timer Compare Value Register)

+  ret

+

+

+ASM_PFX(ArmWriteCntvCval):

+  msr   cntv_cval_el0, x0        // write to  CNTV_CTVAL (Virtual Timer Compare Value Register)

+  ret

+

+

+ASM_PFX(ArmReadCntvOff):

+  mrs   x0, cntvoff_el2          // Read CNTVOFF (virtual Offset register)

+  ret

+

+

+ASM_PFX(ArmWriteCntvOff):

+  msr   cntvoff_el2, x0          // Write to CNTVOFF (Virtual Offset register)

+  ret

+

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
new file mode 100644
index 0000000..a4e1f20
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
@@ -0,0 +1,267 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Portions 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 <Uefi.h>

+#include <Chipset/AArch64.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/IoLib.h>

+#include "AArch64Lib.h"

+#include "ArmLibPrivate.h"

+

+ARM_CACHE_TYPE

+EFIAPI

+ArmCacheType (

+  VOID

+  )

+{

+  return ARM_CACHE_TYPE_WRITE_BACK;

+}

+

+ARM_CACHE_ARCHITECTURE

+EFIAPI

+ArmCacheArchitecture (

+  VOID

+  )

+{

+  UINT32 CLIDR = ReadCLIDR ();

+

+  return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me

+}

+

+BOOLEAN

+EFIAPI

+ArmDataCachePresent (

+  VOID

+  )

+{

+  UINT32 CLIDR = ReadCLIDR ();

+

+  if ((CLIDR & 0x2) == 0x2) {

+    // Instruction cache exists

+    return TRUE;

+  }

+  if ((CLIDR & 0x7) == 0x4) {

+    // Unified cache

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheSize (

+  VOID

+  )

+{

+  UINT32 NumSets;

+  UINT32 Associativity;

+  UINT32 LineSize;

+  UINT32 CCSIDR = ReadCCSIDR (0);

+

+  LineSize      = (1 << ((CCSIDR & 0x7) + 2));

+  Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;

+  NumSets       = ((CCSIDR >> 13) & 0x7fff) + 1;

+

+  // LineSize is in words (4 byte chunks)

+  return  NumSets * Associativity * LineSize * 4;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheAssociativity (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (0);

+

+  return ((CCSIDR >> 3) & 0x3ff) + 1;

+}

+

+UINTN

+ArmDataCacheSets (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (0);

+

+  return ((CCSIDR >> 13) & 0x7fff) + 1;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheLineLength (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (0) & 7;

+

+  // * 4 converts to bytes

+  return (1 << (CCSIDR + 2)) * 4;

+}

+

+BOOLEAN

+EFIAPI

+ArmInstructionCachePresent (

+  VOID

+  )

+{

+  UINT32 CLIDR = ReadCLIDR ();

+

+  if ((CLIDR & 1) == 1) {

+    // Instruction cache exists

+    return TRUE;

+  }

+  if ((CLIDR & 0x7) == 0x4) {

+    // Unified cache

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheSize (

+  VOID

+  )

+{

+  UINT32 NumSets;

+  UINT32 Associativity;

+  UINT32 LineSize;

+  UINT32 CCSIDR = ReadCCSIDR (1);

+

+  LineSize      = (1 << ((CCSIDR & 0x7) + 2));

+  Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;

+  NumSets       = ((CCSIDR >> 13) & 0x7fff) + 1;

+

+  // LineSize is in words (4 byte chunks)

+  return  NumSets * Associativity * LineSize * 4;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheAssociativity (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (1);

+

+  return ((CCSIDR >> 3) & 0x3ff) + 1;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheSets (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (1);

+

+  return ((CCSIDR >> 13) & 0x7fff) + 1;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheLineLength (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (1) & 7;

+

+  // * 4 converts to bytes

+  return (1 << (CCSIDR + 2)) * 4;

+}

+

+

+VOID

+AArch64DataCacheOperation (

+  IN  AARCH64_CACHE_OPERATION  DataCacheOperation

+  )

+{

+  UINTN     SavedInterruptState;

+

+  SavedInterruptState = ArmGetInterruptState ();

+  ArmDisableInterrupts();

+

+  AArch64AllDataCachesOperation (DataCacheOperation);

+

+  ArmDrainWriteBuffer ();

+

+  if (SavedInterruptState) {

+    ArmEnableInterrupts ();

+  }

+}

+

+

+VOID

+AArch64PoUDataCacheOperation (

+  IN  AARCH64_CACHE_OPERATION  DataCacheOperation

+  )

+{

+  UINTN     SavedInterruptState;

+

+  SavedInterruptState = ArmGetInterruptState ();

+  ArmDisableInterrupts ();

+

+  AArch64PerformPoUDataCacheOperation (DataCacheOperation);

+

+  ArmDrainWriteBuffer ();

+

+  if (SavedInterruptState) {

+    ArmEnableInterrupts ();

+  }

+}

+

+VOID

+EFIAPI

+ArmInvalidateDataCache (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);

+}

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCache (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);

+}

+

+VOID

+EFIAPI

+ArmCleanDataCache (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);

+}

+

+VOID

+EFIAPI

+ArmCleanDataCacheToPoU (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  AArch64PoUDataCacheOperation (ArmCleanDataCacheEntryBySetWay);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
new file mode 100644
index 0000000..c8bb843
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
@@ -0,0 +1,33 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __AARCH64_LIB_H__

+#define __AARCH64_LIB_H__

+

+typedef VOID (*AARCH64_CACHE_OPERATION)(UINTN);

+

+

+VOID

+AArch64PerformPoUDataCacheOperation (

+  IN  AARCH64_CACHE_OPERATION  DataCacheOperation

+  );

+

+VOID

+AArch64AllDataCachesOperation (

+  IN  AARCH64_CACHE_OPERATION  DataCacheOperation

+  );

+

+#endif // __AARCH64_LIB_H__

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
new file mode 100644
index 0000000..e524784
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
@@ -0,0 +1,46 @@
+#/** @file

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# Portions 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                      = AArch64Lib

+  FILE_GUID                      = ef20ddf5-b334-47b3-94cf-52ff44c29138

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.AARCH64]

+  AArch64Lib.c

+  AArch64Mmu.c

+  AArch64ArchTimer.c

+  ArmLibSupportV8.S

+  AArch64Support.S

+  AArch64ArchTimerSupport.S

+

+  ../Common/AArch64/ArmLibSupport.S

+  ../Common/ArmLib.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  MemoryAllocationLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
new file mode 100644
index 0000000..3a99e1b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
@@ -0,0 +1,48 @@
+#/** @file

+#

+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#  Portions copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = AArch64LibPrePi

+  FILE_GUID                      = fd72688d-dbd8-4cf2-91a3-15171dea7816

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ArmLibSupportV8.S

+  AArch64Support.S

+

+  ../Common/AArch64/ArmLibSupport.S

+  ../Common/ArmLib.c

+

+  AArch64Lib.c

+  AArch64Mmu.c

+

+  AArch64ArchTimer.c

+  AArch64ArchTimerSupport.S

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PrePiLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
new file mode 100644
index 0000000..57ac694
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
@@ -0,0 +1,43 @@
+#/* @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                      = AArch64Lib

+  FILE_GUID                      = eb7441e4-3ddf-48b8-a009-14f428b19e49

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ArmLibSupportV8.S

+  AArch64Support.S

+

+  ../Common/AArch64/ArmLibSupport.S

+  ../Common/ArmLib.c

+

+  AArch64Lib.c

+

+  AArch64ArchTimer.c

+  AArch64ArchTimerSupport.S

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
new file mode 100644
index 0000000..f215fe9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
@@ -0,0 +1,701 @@
+/** @file

+*  File managing the MMU for ARMv8 architecture

+*

+*  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.

+*

+**/

+

+#include <Uefi.h>

+#include <Chipset/AArch64.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include "AArch64Lib.h"

+#include "ArmLibPrivate.h"

+

+// We use this index definition to define an invalid block entry

+#define TT_ATTR_INDX_INVALID    ((UINT32)~0)

+

+STATIC

+UINT64

+ArmMemoryAttributeToPageAttribute (

+  IN ARM_MEMORY_REGION_ATTRIBUTES  Attributes

+  )

+{

+  switch (Attributes) {

+  case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:

+    return TT_ATTR_INDX_MEMORY_WRITE_BACK;

+  case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:

+    return TT_ATTR_INDX_MEMORY_WRITE_THROUGH;

+  case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:

+    return TT_ATTR_INDX_DEVICE_MEMORY;

+  case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:

+    return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;

+  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:

+    return TT_ATTR_INDX_MEMORY_WRITE_BACK;

+  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:

+    return TT_ATTR_INDX_MEMORY_WRITE_THROUGH;

+  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:

+    return TT_ATTR_INDX_DEVICE_MEMORY;

+  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:

+    return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;

+  default:

+    ASSERT(0);

+    return TT_ATTR_INDX_DEVICE_MEMORY;

+  }

+}

+

+UINT64

+PageAttributeToGcdAttribute (

+  IN UINT64 PageAttributes

+  )

+{

+  UINT64  GcdAttributes;

+

+  switch (PageAttributes & TT_ATTR_INDX_MASK) {

+  case TT_ATTR_INDX_DEVICE_MEMORY:

+    GcdAttributes = EFI_MEMORY_UC;

+    break;

+  case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:

+    GcdAttributes = EFI_MEMORY_WC;

+    break;

+  case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:

+    GcdAttributes = EFI_MEMORY_WT;

+    break;

+  case TT_ATTR_INDX_MEMORY_WRITE_BACK:

+    GcdAttributes = EFI_MEMORY_WB;

+    break;

+  default:

+    DEBUG ((EFI_D_ERROR, "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n", PageAttributes));

+    ASSERT (0);

+    // The Global Coherency Domain (GCD) value is defined as a bit set.

+    // Returning 0 means no attribute has been set.

+    GcdAttributes = 0;

+  }

+

+  // Determine protection attributes

+  if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) || ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {

+    // Read only cases map to write-protect

+    GcdAttributes |= EFI_MEMORY_WP;

+  }

+

+  // Process eXecute Never attribute

+  if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0 ) {

+    GcdAttributes |= EFI_MEMORY_XP;

+  }

+

+  return GcdAttributes;

+}

+

+UINT64

+GcdAttributeToPageAttribute (

+  IN UINT64 GcdAttributes

+  )

+{

+  UINT64  PageAttributes;

+

+  switch (GcdAttributes & 0xFF) {

+  case EFI_MEMORY_UC:

+    PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY;

+    break;

+  case EFI_MEMORY_WC:

+    PageAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;

+    break;

+  case EFI_MEMORY_WT:

+    PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH;

+    break;

+  case EFI_MEMORY_WB:

+    PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK;

+    break;

+  default:

+    DEBUG ((EFI_D_ERROR, "GcdAttributeToPageAttribute: 0x%X attributes is not supported.\n", GcdAttributes));

+    ASSERT (0);

+    // If no match has been found then we mark the memory as device memory.

+    // The only side effect of using device memory should be a slow down in the performance.

+    PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY;

+  }

+

+  // Determine protection attributes

+  if (GcdAttributes & EFI_MEMORY_WP) {

+    // Read only cases map to write-protect

+    PageAttributes |= TT_AP_RO_RO;

+  }

+

+  // Process eXecute Never attribute

+  if (GcdAttributes & EFI_MEMORY_XP) {

+    PageAttributes |= (TT_PXN_MASK | TT_UXN_MASK);

+  }

+

+  return PageAttributes;

+}

+

+ARM_MEMORY_REGION_ATTRIBUTES

+GcdAttributeToArmAttribute (

+  IN UINT64 GcdAttributes

+  )

+{

+  switch (GcdAttributes & 0xFF) {

+  case EFI_MEMORY_UC:

+    return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;

+  case EFI_MEMORY_WC:

+    return ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;

+  case EFI_MEMORY_WT:

+    return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;

+  case EFI_MEMORY_WB:

+    return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;

+  default:

+    DEBUG ((EFI_D_ERROR, "GcdAttributeToArmAttribute: 0x%lX attributes is not supported.\n", GcdAttributes));

+    ASSERT (0);

+    return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;

+  }

+}

+

+// Describe the T0SZ values for each translation table level

+typedef struct {

+  UINTN     MinT0SZ;

+  UINTN     MaxT0SZ;

+  UINTN     LargestT0SZ; // Generally (MaxT0SZ == LargestT0SZ) but at the Level3 Table

+                         // the MaxT0SZ is not at the boundary of the table

+} T0SZ_DESCRIPTION_PER_LEVEL;

+

+// Map table for the corresponding Level of Table

+STATIC CONST T0SZ_DESCRIPTION_PER_LEVEL T0SZPerTableLevel[] = {

+    { 16, 24, 24 }, // Table Level 0

+    { 25, 33, 33 }, // Table Level 1

+    { 34, 39, 42 }  // Table Level 2

+};

+

+VOID

+GetRootTranslationTableInfo (

+  IN UINTN     T0SZ,

+  OUT UINTN   *TableLevel,

+  OUT UINTN   *TableEntryCount

+  )

+{

+  UINTN Index;

+

+  // Identify the level of the root table from the given T0SZ

+  for (Index = 0; Index < sizeof (T0SZPerTableLevel) / sizeof (T0SZ_DESCRIPTION_PER_LEVEL); Index++) {

+    if (T0SZ <= T0SZPerTableLevel[Index].MaxT0SZ) {

+      break;

+    }

+  }

+

+  // If we have not found the corresponding maximum T0SZ then we use the last one

+  if (Index == sizeof (T0SZPerTableLevel) / sizeof (T0SZ_DESCRIPTION_PER_LEVEL)) {

+    Index--;

+  }

+

+  // Get the level of the root table

+  if (TableLevel) {

+    *TableLevel = Index;

+  }

+

+  // The Size of the Table is 2^(T0SZ-LargestT0SZ)

+  if (TableEntryCount) {

+    *TableEntryCount = 1 << (T0SZPerTableLevel[Index].LargestT0SZ - T0SZ + 1);

+  }

+}

+

+STATIC

+VOID

+LookupAddresstoRootTable (

+  IN  UINT64  MaxAddress,

+  OUT UINTN  *T0SZ,

+  OUT UINTN  *TableEntryCount

+  )

+{

+  UINTN TopBit;

+

+  // Check the parameters are not NULL

+  ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL));

+

+  // Look for the highest bit set in MaxAddress

+  for (TopBit = 63; TopBit != 0; TopBit--) {

+    if ((1ULL << TopBit) & MaxAddress) {

+      // MaxAddress top bit is found

+      TopBit = TopBit + 1;

+      break;

+    }

+  }

+  ASSERT (TopBit != 0);

+

+  // Calculate T0SZ from the top bit of the MaxAddress

+  *T0SZ = 64 - TopBit;

+

+  // Get the Table info from T0SZ

+  GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount);

+}

+

+STATIC

+UINT64*

+GetBlockEntryListFromAddress (

+  IN  UINT64       *RootTable,

+  IN  UINT64        RegionStart,

+  OUT UINTN        *TableLevel,

+  IN OUT UINT64    *BlockEntrySize,

+  IN OUT UINT64   **LastBlockEntry

+  )

+{

+  UINTN   RootTableLevel;

+  UINTN   RootTableEntryCount;

+  UINT64 *TranslationTable;

+  UINT64 *BlockEntry;

+  UINT64 *SubTableBlockEntry;

+  UINT64  BlockEntryAddress;

+  UINTN   BaseAddressAlignment;

+  UINTN   PageLevel;

+  UINTN   Index;

+  UINTN   IndexLevel;

+  UINTN   T0SZ;

+  UINT64  Attributes;

+  UINT64  TableAttributes;

+

+  // Initialize variable

+  BlockEntry = NULL;

+

+  // Ensure the parameters are valid

+  if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {

+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);

+    return NULL;

+  }

+

+  // Ensure the Region is aligned on 4KB boundary

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

+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);

+    return NULL;

+  }

+

+  // Ensure the required size is aligned on 4KB boundary

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

+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);

+    return NULL;

+  }

+

+  //

+  // Calculate LastBlockEntry from T0SZ - this is the last block entry of the root Translation table

+  //

+  T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;

+  // Get the Table info from T0SZ

+  GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);

+  // The last block of the root table depends on the number of entry in this table

+  *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(RootTable, RootTableEntryCount);

+

+  // If the start address is 0x0 then we use the size of the region to identify the alignment

+  if (RegionStart == 0) {

+    // Identify the highest possible alignment for the Region Size

+    for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; BaseAddressAlignment++) {

+      if ((1 << BaseAddressAlignment) & *BlockEntrySize) {

+        break;

+      }

+    }

+  } else {

+    // Identify the highest possible alignment for the Base Address

+    for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; BaseAddressAlignment++) {

+      if ((1 << BaseAddressAlignment) & RegionStart) {

+        break;

+      }

+    }

+  }

+

+  // Identify the Page Level the RegionStart must belongs to

+  PageLevel = 3 - ((BaseAddressAlignment - 12) / 9);

+

+  // If the required size is smaller than the current block size then we need to go to the page below.

+  // The PageLevel was calculated on the Base Address alignment but did not take in account the alignment

+  // of the allocation size

+  if (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {

+    // It does not fit so we need to go a page level above

+    PageLevel++;

+  }

+

+  // Expose the found PageLevel to the caller

+  *TableLevel = PageLevel;

+

+  // Now, we have the Table Level we can get the Block Size associated to this table

+  *BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);

+

+  //

+  // Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries

+  //

+

+  TranslationTable = RootTable;

+  for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {

+    BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);

+

+    if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {

+      // Go to the next table

+      TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);

+

+      // If we are at the last level then update the output

+      if (IndexLevel == PageLevel) {

+        // And get the appropriate BlockEntry at the next level

+        BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel + 1, RegionStart);

+

+        // Set the last block for this new table

+        *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);

+      }

+    } else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {

+      // If we are not at the last level then we need to split this BlockEntry

+      if (IndexLevel != PageLevel) {

+        // Retrieve the attributes from the block entry

+        Attributes = *BlockEntry & TT_ATTRIBUTES_MASK;

+

+        // Convert the block entry attributes into Table descriptor attributes

+        TableAttributes = TT_TABLE_AP_NO_PERMISSION;

+        if (Attributes & TT_PXN_MASK) {

+          TableAttributes = TT_TABLE_PXN;

+        }

+        if (Attributes & TT_UXN_MASK) {

+          TableAttributes = TT_TABLE_XN;

+        }

+        if (Attributes & TT_NS) {

+          TableAttributes = TT_TABLE_NS;

+        }

+

+        // Get the address corresponding at this entry

+        BlockEntryAddress = RegionStart;

+        BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);

+        // Shift back to right to set zero before the effective address

+        BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);

+

+        // Set the correct entry type for the next page level

+        if ((IndexLevel + 1) == 3) {

+          Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;

+        } else {

+          Attributes |= TT_TYPE_BLOCK_ENTRY;

+        }

+

+        // Create a new translation table

+        TranslationTable = (UINT64*)AllocatePages (EFI_SIZE_TO_PAGES((TT_ENTRY_COUNT * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE));

+        if (TranslationTable == NULL) {

+          return NULL;

+        }

+        TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);

+

+        // Populate the newly created lower level table

+        SubTableBlockEntry = TranslationTable;

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

+          *SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));

+          SubTableBlockEntry++;

+        }

+

+        // Fill the BlockEntry with the new TranslationTable

+        *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY;

+        // Update the last block entry with the newly created translation table

+        *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);

+

+        // Block Entry points at the beginning of the Translation Table

+        BlockEntry = TranslationTable;

+      }

+    } else {

+      if (IndexLevel != PageLevel) {

+        //

+        // Case when we have an Invalid Entry and we are at a page level above of the one targetted.

+        //

+

+        // Create a new translation table

+        TranslationTable = (UINT64*)AllocatePages (EFI_SIZE_TO_PAGES((TT_ENTRY_COUNT * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE));

+        if (TranslationTable == NULL) {

+          return NULL;

+        }

+        TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);

+

+        ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));

+

+        // Fill the new BlockEntry with the TranslationTable

+        *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;

+        // Update the last block entry with the newly created translation table

+        *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);

+      } else {

+        //

+        // Case when the new region is part of an existing page table

+        //

+        *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);

+      }

+    }

+  }

+

+  return BlockEntry;

+}

+

+STATIC

+RETURN_STATUS

+FillTranslationTable (

+  IN  UINT64                        *RootTable,

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion

+  )

+{

+  UINT64  Attributes;

+  UINT32  Type;

+  UINT64  RegionStart;

+  UINT64  RemainingRegionLength;

+  UINT64 *BlockEntry;

+  UINT64 *LastBlockEntry;

+  UINT64  BlockEntrySize;

+  UINTN   TableLevel;

+

+  // Ensure the Length is aligned on 4KB boundary

+  if ((MemoryRegion->Length == 0) || ((MemoryRegion->Length & (SIZE_4KB - 1)) != 0)) {

+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  // Variable initialization

+  Attributes = ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF;

+  RemainingRegionLength = MemoryRegion->Length;

+  RegionStart = MemoryRegion->VirtualBase;

+

+  do {

+    // Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor

+    // such as the the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor

+    BlockEntrySize = RemainingRegionLength;

+    BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);

+    if (BlockEntry == NULL) {

+      // GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables

+      return RETURN_OUT_OF_RESOURCES;

+    }

+

+    if (TableLevel != 3) {

+      Type = TT_TYPE_BLOCK_ENTRY;

+    } else {

+      Type = TT_TYPE_BLOCK_ENTRY_LEVEL3;

+    }

+

+    do {

+      // Fill the Block Entry with attribute and output block address

+      *BlockEntry = (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;

+

+      // Go to the next BlockEntry

+      RegionStart += BlockEntrySize;

+      RemainingRegionLength -= BlockEntrySize;

+      BlockEntry++;

+    } while ((RemainingRegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));

+  } while (RemainingRegionLength != 0);

+

+  return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+SetMemoryAttributes (

+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,

+  IN UINT64                    Length,

+  IN UINT64                    Attributes,

+  IN EFI_PHYSICAL_ADDRESS      VirtualMask

+  )

+{

+  RETURN_STATUS                Status;

+  ARM_MEMORY_REGION_DESCRIPTOR MemoryRegion;

+  UINT64                      *TranslationTable;

+

+  MemoryRegion.PhysicalBase = BaseAddress;

+  MemoryRegion.VirtualBase = BaseAddress;

+  MemoryRegion.Length = Length;

+  MemoryRegion.Attributes = GcdAttributeToArmAttribute (Attributes);

+

+  TranslationTable = ArmGetTTBR0BaseAddress ();

+

+  Status = FillTranslationTable (TranslationTable, &MemoryRegion);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks

+  // flush and invalidate pages

+  ArmCleanInvalidateDataCache ();

+

+  ArmInvalidateInstructionCache ();

+

+  // Invalidate all TLB entries so changes are synced

+  ArmInvalidateTlb ();

+

+  return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+EFIAPI

+ArmConfigureMmu (

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,

+  OUT VOID                         **TranslationTableBase OPTIONAL,

+  OUT UINTN                         *TranslationTableSize OPTIONAL

+  )

+{

+  VOID*                         TranslationTable;

+  UINTN                         TranslationTablePageCount;

+  UINT32                        TranslationTableAttribute;

+  ARM_MEMORY_REGION_DESCRIPTOR *MemoryTableEntry;

+  UINT64                        MaxAddress;

+  UINT64                        TopAddress;

+  UINTN                         T0SZ;

+  UINTN                         RootTableEntryCount;

+  UINT64                        TCR;

+  RETURN_STATUS                 Status;

+

+  if(MemoryTable == NULL) {

+    ASSERT (MemoryTable != NULL);

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  // Identify the highest address of the memory table

+  MaxAddress = MemoryTable->PhysicalBase + MemoryTable->Length - 1;

+  MemoryTableEntry = MemoryTable;

+  while (MemoryTableEntry->Length != 0) {

+    TopAddress = MemoryTableEntry->PhysicalBase + MemoryTableEntry->Length - 1;

+    if (TopAddress > MaxAddress) {

+      MaxAddress = TopAddress;

+    }

+    MemoryTableEntry++;

+  }

+

+  // Lookup the Table Level to get the information

+  LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);

+

+  //

+  // Set TCR that allows us to retrieve T0SZ in the subsequent functions

+  //

+  // Ideally we will be running at EL2, but should support EL1 as well.

+  // UEFI should not run at EL3.

+  if (ArmReadCurrentEL () == AARCH64_EL2) {

+    //Note: Bits 23 and 31 are reserved(RES1) bits in TCR_EL2

+    TCR = T0SZ | (1UL << 31) | (1UL << 23) | TCR_TG0_4KB;

+

+    // Set the Physical Address Size using MaxAddress

+    if (MaxAddress < SIZE_4GB) {

+      TCR |= TCR_PS_4GB;

+    } else if (MaxAddress < SIZE_64GB) {

+      TCR |= TCR_PS_64GB;

+    } else if (MaxAddress < SIZE_1TB) {

+      TCR |= TCR_PS_1TB;

+    } else if (MaxAddress < SIZE_4TB) {

+      TCR |= TCR_PS_4TB;

+    } else if (MaxAddress < SIZE_16TB) {

+      TCR |= TCR_PS_16TB;

+    } else if (MaxAddress < SIZE_256TB) {

+      TCR |= TCR_PS_256TB;

+    } else {

+      DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));

+      ASSERT (0); // Bigger than 48-bit memory space are not supported

+      return RETURN_UNSUPPORTED;

+    }

+  } else if (ArmReadCurrentEL () == AARCH64_EL1) {

+    TCR = T0SZ | TCR_TG0_4KB;

+

+    // Set the Physical Address Size using MaxAddress

+    if (MaxAddress < SIZE_4GB) {

+      TCR |= TCR_IPS_4GB;

+    } else if (MaxAddress < SIZE_64GB) {

+      TCR |= TCR_IPS_64GB;

+    } else if (MaxAddress < SIZE_1TB) {

+      TCR |= TCR_IPS_1TB;

+    } else if (MaxAddress < SIZE_4TB) {

+      TCR |= TCR_IPS_4TB;

+    } else if (MaxAddress < SIZE_16TB) {

+      TCR |= TCR_IPS_16TB;

+    } else if (MaxAddress < SIZE_256TB) {

+      TCR |= TCR_IPS_256TB;

+    } else {

+      DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));

+      ASSERT (0); // Bigger than 48-bit memory space are not supported

+      return RETURN_UNSUPPORTED;

+    }

+  } else {

+    ASSERT (0); // UEFI is only expected to run at EL2 and EL1, not EL3.

+    return RETURN_UNSUPPORTED;

+  }

+

+  // Set TCR

+  ArmSetTCR (TCR);

+

+  // Allocate pages for translation table

+  TranslationTablePageCount = EFI_SIZE_TO_PAGES((RootTableEntryCount * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE);

+  TranslationTable = AllocatePages (TranslationTablePageCount);

+  if (TranslationTable == NULL) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  TranslationTable = (VOID*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);

+  // We set TTBR0 just after allocating the table to retrieve its location from the subsequent

+  // functions without needing to pass this value across the functions. The MMU is only enabled

+  // after the translation tables are populated.

+  ArmSetTTBR0 (TranslationTable);

+

+  if (TranslationTableBase != NULL) {

+    *TranslationTableBase = TranslationTable;

+  }

+

+  if (TranslationTableSize != NULL) {

+    *TranslationTableSize = RootTableEntryCount * sizeof(UINT64);

+  }

+

+  ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));

+

+  // Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs

+  ArmDisableMmu ();

+  ArmDisableDataCache ();

+  ArmDisableInstructionCache ();

+

+  // Make sure nothing sneaked into the cache

+  ArmCleanInvalidateDataCache ();

+  ArmInvalidateInstructionCache ();

+

+  TranslationTableAttribute = TT_ATTR_INDX_INVALID;

+  while (MemoryTable->Length != 0) {

+    // Find the memory attribute for the Translation Table

+    if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) &&

+        ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {

+      TranslationTableAttribute = MemoryTable->Attributes;

+    }

+

+    Status = FillTranslationTable (TranslationTable, MemoryTable);

+    if (RETURN_ERROR (Status)) {

+      goto FREE_TRANSLATION_TABLE;

+    }

+    MemoryTable++;

+  }

+

+  // Translate the Memory Attributes into Translation Table Register Attributes

+  if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||

+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {

+    TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_NON_CACHEABLE | TCR_RGN_INNER_NON_CACHEABLE;

+  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||

+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {

+    TCR |= TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WRITE_BACK_ALLOC | TCR_RGN_INNER_WRITE_BACK_ALLOC;

+  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||

+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {

+    TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_WRITE_THROUGH | TCR_RGN_INNER_WRITE_THROUGH;

+  } else {

+    // If we failed to find a mapping that contains the root translation table then it probably means the translation table

+    // is not mapped in the given memory map.

+    ASSERT (0);

+    Status = RETURN_UNSUPPORTED;

+    goto FREE_TRANSLATION_TABLE;

+  }

+

+  // Set again TCR after getting the Translation Table attributes

+  ArmSetTCR (TCR);

+

+  ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) |                      // mapped to EFI_MEMORY_UC

+              MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC

+              MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT

+              MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK));       // mapped to EFI_MEMORY_WB

+

+  ArmDisableAlignmentCheck ();

+  ArmEnableInstructionCache ();

+  ArmEnableDataCache ();

+

+  ArmEnableMmu ();

+  return RETURN_SUCCESS;

+

+FREE_TRANSLATION_TABLE:

+  FreePages (TranslationTable, TranslationTablePageCount);

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
new file mode 100644
index 0000000..bdede48
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
@@ -0,0 +1,498 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#include <Chipset/AArch64.h>

+#include <AsmMacroIoLibV8.h>

+

+.text

+.align 3

+

+GCC_ASM_EXPORT (ArmInvalidateInstructionCache)

+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)

+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)

+GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)

+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryBySetWay)

+GCC_ASM_EXPORT (ArmDrainWriteBuffer)

+GCC_ASM_EXPORT (ArmEnableMmu)

+GCC_ASM_EXPORT (ArmDisableMmu)

+GCC_ASM_EXPORT (ArmDisableCachesAndMmu)

+GCC_ASM_EXPORT (ArmMmuEnabled)

+GCC_ASM_EXPORT (ArmEnableDataCache)

+GCC_ASM_EXPORT (ArmDisableDataCache)

+GCC_ASM_EXPORT (ArmEnableInstructionCache)

+GCC_ASM_EXPORT (ArmDisableInstructionCache)

+GCC_ASM_EXPORT (ArmDisableAlignmentCheck)

+GCC_ASM_EXPORT (ArmEnableAlignmentCheck)

+GCC_ASM_EXPORT (ArmEnableBranchPrediction)

+GCC_ASM_EXPORT (ArmDisableBranchPrediction)

+GCC_ASM_EXPORT (AArch64AllDataCachesOperation)

+GCC_ASM_EXPORT (AArch64PerformPoUDataCacheOperation)

+GCC_ASM_EXPORT (ArmDataMemoryBarrier)

+GCC_ASM_EXPORT (ArmDataSyncronizationBarrier)

+GCC_ASM_EXPORT (ArmInstructionSynchronizationBarrier)

+GCC_ASM_EXPORT (ArmWriteVBar)

+GCC_ASM_EXPORT (ArmReadVBar)

+GCC_ASM_EXPORT (ArmEnableVFP)

+GCC_ASM_EXPORT (ArmCallWFI)

+GCC_ASM_EXPORT (ArmReadMpidr)

+GCC_ASM_EXPORT (ArmReadTpidrurw)

+GCC_ASM_EXPORT (ArmWriteTpidrurw)

+GCC_ASM_EXPORT (ArmIsArchTimerImplemented)

+GCC_ASM_EXPORT (ArmReadIdPfr0)

+GCC_ASM_EXPORT (ArmReadIdPfr1)

+GCC_ASM_EXPORT (ArmWriteHcr)

+GCC_ASM_EXPORT (ArmReadCurrentEL)

+

+.set CTRL_M_BIT,      (1 << 0)

+.set CTRL_A_BIT,      (1 << 1)

+.set CTRL_C_BIT,      (1 << 2)

+.set CTRL_I_BIT,      (1 << 12)

+.set CTRL_V_BIT,      (1 << 12)

+.set CPACR_VFP_BITS,  (3 << 20)

+

+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):

+  dc      ivac, x0    // Invalidate single data cache line

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmCleanDataCacheEntryByMVA):

+  dc      cvac, x0    // Clean single data cache line

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):

+  dc      civac, x0   // Clean and invalidate single data cache line

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmInvalidateDataCacheEntryBySetWay):

+  dc      isw, x0     // Invalidate this line

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay):

+  dc      cisw, x0    // Clean and Invalidate this line

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmCleanDataCacheEntryBySetWay):

+  dc      csw, x0     // Clean this line

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmInvalidateInstructionCache):

+  ic      iallu       // Invalidate entire instruction cache

+  dsb     sy

+  isb

+  ret

+

+

+ASM_PFX(ArmEnableMmu):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1       // Read System control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2       // Read System control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3       // Read System control register EL3

+4: orr     x0, x0, #CTRL_M_BIT // Set MMU enable bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: tlbi    vmalle1

+   isb

+   msr     sctlr_el1, x0       // Write back

+   b       4f

+2: tlbi    alle2

+   isb

+   msr     sctlr_el2, x0       // Write back

+   b       4f

+3: tlbi    alle3

+   isb

+   msr     sctlr_el3, x0       // Write back

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmDisableMmu):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Read System Control Register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Read System Control Register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Read System Control Register EL3

+4: and     x0, x0, #~CTRL_M_BIT  // Clear MMU enable bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back

+   tlbi    vmalle1

+   b       4f

+2: msr     sctlr_el2, x0        // Write back

+   tlbi    alle2

+   b       4f

+3: msr     sctlr_el3, x0        // Write back

+   tlbi    alle3

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmDisableCachesAndMmu):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: mov     x1, #~(CTRL_M_BIT | CTRL_C_BIT | CTRL_I_BIT)  // Disable MMU, D & I caches

+   and     x0, x0, x1

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       4f

+2: msr     sctlr_el2, x0        // Write back control register

+   b       4f

+3: msr     sctlr_el3, x0        // Write back control register

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmMmuEnabled):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: and     x0, x0, #CTRL_M_BIT

+   ret

+

+

+ASM_PFX(ArmEnableDataCache):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: orr     x0, x0, #CTRL_C_BIT  // Set C bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       4f

+2: msr     sctlr_el2, x0        // Write back control register

+   b       4f

+3: msr     sctlr_el3, x0        // Write back control register

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmDisableDataCache):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: and     x0, x0, #~CTRL_C_BIT  // Clear C bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       4f

+2: msr     sctlr_el2, x0        // Write back control register

+   b       4f

+3: msr     sctlr_el3, x0        // Write back control register

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmEnableInstructionCache):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: orr     x0, x0, #CTRL_I_BIT  // Set I bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       4f

+2: msr     sctlr_el2, x0        // Write back control register

+   b       4f

+3: msr     sctlr_el3, x0        // Write back control register

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmDisableInstructionCache):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: and     x0, x0, #~CTRL_I_BIT  // Clear I bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       4f

+2: msr     sctlr_el2, x0        // Write back control register

+   b       4f

+3: msr     sctlr_el3, x0        // Write back control register

+4: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmEnableAlignmentCheck):

+   EL1_OR_EL2(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       3f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+3: orr     x0, x0, #CTRL_A_BIT  // Set A (alignment check) bit

+   EL1_OR_EL2(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       3f

+2: msr     sctlr_el2, x0        // Write back control register

+3: dsb     sy

+   isb

+   ret

+

+

+ASM_PFX(ArmDisableAlignmentCheck):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs     x0, sctlr_el1        // Get control register EL1

+   b       4f

+2: mrs     x0, sctlr_el2        // Get control register EL2

+   b       4f

+3: mrs     x0, sctlr_el3        // Get control register EL3

+4: and     x0, x0, #~CTRL_A_BIT  // Clear A (alignment check) bit

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr     sctlr_el1, x0        // Write back control register

+   b       4f

+2: msr     sctlr_el2, x0        // Write back control register

+   b       4f

+3: msr     sctlr_el3, x0        // Write back control register

+4: dsb     sy

+   isb

+   ret

+

+

+// Always turned on in AArch64. Else implementation specific. Leave in for C compatibility for now

+ASM_PFX(ArmEnableBranchPrediction):

+  ret

+

+

+// Always turned on in AArch64. Else implementation specific. Leave in for C compatibility for now.

+ASM_PFX(ArmDisableBranchPrediction):

+  ret

+

+

+ASM_PFX(AArch64AllDataCachesOperation):

+// We can use regs 0-7 and 9-15 without having to save/restore.

+// Save our link register on the stack. - The stack must always be quad-word aligned

+  str   x30, [sp, #-16]!

+  mov   x1, x0                  // Save Function call in x1

+  mrs   x6, clidr_el1           // Read EL1 CLIDR

+  and   x3, x6, #0x7000000      // Mask out all but Level of Coherency (LoC)

+  lsr   x3, x3, #23             // Left align cache level value - the level is shifted by 1 to the

+                                // right to ease the access to CSSELR and the Set/Way operation.

+  cbz   x3, L_Finished          // No need to clean if LoC is 0

+  mov   x10, #0                 // Start clean at cache level 0

+  b     Loop1

+

+ASM_PFX(AArch64PerformPoUDataCacheOperation):

+// We can use regs 0-7 and 9-15 without having to save/restore.

+// Save our link register on the stack. - The stack must always be quad-word aligned

+  str   x30, [sp, #-16]!

+  mov   x1, x0                  // Save Function call in x1

+  mrs   x6, clidr_el1           // Read EL1 CLIDR

+  and   x3, x6, #0x38000000     // Mask out all but Point of Unification (PoU)

+  lsr   x3, x3, #26             // Left align cache level value - the level is shifted by 1 to the

+                                // right to ease the access to CSSELR and the Set/Way operation.

+  cbz   x3, L_Finished          // No need to clean if LoC is 0

+  mov   x10, #0                 // Start clean at cache level 0

+

+Loop1:

+  add   x2, x10, x10, lsr #1    // Work out 3x cachelevel for cache info

+  lsr   x12, x6, x2             // bottom 3 bits are the Cache type for this level

+  and   x12, x12, #7            // get those 3 bits alone

+  cmp   x12, #2                 // what cache at this level?

+  b.lt  L_Skip                  // no cache or only instruction cache at this level

+  msr   csselr_el1, x10         // write the Cache Size selection register with current level (CSSELR)

+  isb                           // isb to sync the change to the CacheSizeID reg

+  mrs   x12, ccsidr_el1         // reads current Cache Size ID register (CCSIDR)

+  and   x2, x12, #0x7           // extract the line length field

+  add   x2, x2, #4              // add 4 for the line length offset (log2 16 bytes)

+  mov   x4, #0x400

+  sub   x4, x4, #1

+  and   x4, x4, x12, lsr #3     // x4 is the max number on the way size (right aligned)

+  clz   w5, w4                  // w5 is the bit position of the way size increment

+  mov   x7, #0x00008000

+  sub   x7, x7, #1

+  and   x7, x7, x12, lsr #13    // x7 is the max number of the index size (right aligned)

+

+Loop2:

+  mov   x9, x4                  // x9 working copy of the max way size (right aligned)

+

+Loop3:

+  lsl   x11, x9, x5

+  orr   x0, x10, x11            // factor in the way number and cache number

+  lsl   x11, x7, x2

+  orr   x0, x0, x11             // factor in the index number

+

+  blr   x1                      // Goto requested cache operation

+

+  subs  x9, x9, #1              // decrement the way number

+  b.ge  Loop3

+  subs  x7, x7, #1              // decrement the index

+  b.ge  Loop2

+L_Skip:

+  add   x10, x10, #2            // increment the cache number

+  cmp   x3, x10

+  b.gt  Loop1

+

+L_Finished:

+  dsb   sy

+  isb

+  ldr   x30, [sp], #0x10

+  ret

+

+

+ASM_PFX(ArmDataMemoryBarrier):

+  dmb   sy

+  ret

+

+

+ASM_PFX(ArmDataSyncronizationBarrier):

+ASM_PFX(ArmDrainWriteBuffer):

+  dsb   sy

+  ret

+

+

+ASM_PFX(ArmInstructionSynchronizationBarrier):

+  isb

+  ret

+

+

+ASM_PFX(ArmWriteVBar):

+   EL1_OR_EL2_OR_EL3(x1)

+1: msr   vbar_el1, x0            // Set the Address of the EL1 Vector Table in the VBAR register

+   b     4f

+2: msr   vbar_el2, x0            // Set the Address of the EL2 Vector Table in the VBAR register

+   b     4f

+3: msr   vbar_el3, x0            // Set the Address of the EL3 Vector Table in the VBAR register

+4: isb

+   ret

+

+ASM_PFX(ArmReadVBar):

+   EL1_OR_EL2_OR_EL3(x1)

+1: mrs   x0, vbar_el1            // Set the Address of the EL1 Vector Table in the VBAR register

+   ret

+2: mrs   x0, vbar_el2            // Set the Address of the EL2 Vector Table in the VBAR register

+   ret

+3: mrs   x0, vbar_el3            // Set the Address of the EL3 Vector Table in the VBAR register

+   ret

+

+

+ASM_PFX(ArmEnableVFP):

+  // Check whether floating-point is implemented in the processor.

+  mov   x1, x30                 // Save LR

+  bl    ArmReadIdPfr0           // Read EL1 Processor Feature Register (PFR0)

+  mov   x30, x1                 // Restore LR

+  ands  x0, x0, #AARCH64_PFR0_FP// Extract bits indicating VFP implementation

+  cmp   x0, #0                  // VFP is implemented if '0'.

+  b.ne  4f                      // Exit if VFP not implemented.

+  // FVP is implemented.

+  // Make sure VFP exceptions are not trapped (to any exception level).

+  mrs   x0, cpacr_el1           // Read EL1 Coprocessor Access Control Register (CPACR)

+  orr   x0, x0, #CPACR_VFP_BITS // Disable FVP traps to EL1

+  msr   cpacr_el1, x0           // Write back EL1 Coprocessor Access Control Register (CPACR)

+  mov   x1, #AARCH64_CPTR_TFP   // TFP Bit for trapping VFP Exceptions

+  EL1_OR_EL2_OR_EL3(x2)

+1:ret                           // Not configurable in EL1

+2:mrs   x0, cptr_el2            // Disable VFP traps to EL2

+  bic   x0, x0, x1

+  msr   cptr_el2, x0

+  ret

+3:mrs   x0, cptr_el3            // Disable VFP traps to EL3

+  bic   x0, x0, x1

+  msr   cptr_el3, x0

+4:ret

+

+

+ASM_PFX(ArmCallWFI):

+  wfi

+  ret

+

+

+ASM_PFX(ArmReadMpidr):

+  mrs   x0, mpidr_el1           // read EL1 MPIDR

+  ret

+

+

+// Keep old function names for C compatibilty for now. Change later?

+ASM_PFX(ArmReadTpidrurw):

+  mrs   x0, tpidr_el0           // read tpidr_el0 (v7 TPIDRURW) -> (v8 TPIDR_EL0)

+  ret

+

+

+// Keep old function names for C compatibilty for now. Change later?

+ASM_PFX(ArmWriteTpidrurw):

+  msr   tpidr_el0, x0           // write tpidr_el0 (v7 TPIDRURW) -> (v8 TPIDR_EL0)

+  ret

+

+

+// Arch timers are mandatory on AArch64

+ASM_PFX(ArmIsArchTimerImplemented):

+  mov   x0, #1

+  ret

+

+

+ASM_PFX(ArmReadIdPfr0):

+  mrs   x0, id_aa64pfr0_el1   // Read ID_AA64PFR0 Register

+  ret

+

+

+// Q: id_aa64pfr1_el1 not defined yet. What does this funtion want to access?

+// A: used to setup arch timer. Check if we have security extensions, permissions to set stuff.

+//    See: ArmPkg/Library/ArmArchTimerLib/AArch64/ArmArchTimerLib.c

+//    Not defined yet, but stick in here for now, should read all zeros.

+ASM_PFX(ArmReadIdPfr1):

+  mrs   x0, id_aa64pfr1_el1   // Read ID_PFR1 Register

+  ret

+

+// VOID ArmWriteHcr(UINTN Hcr)

+ASM_PFX(ArmWriteHcr):

+  msr   hcr_el2, x0        // Write the passed HCR value

+  ret

+

+// UINTN ArmReadCurrentEL(VOID)

+ASM_PFX(ArmReadCurrentEL):

+  mrs   x0, CurrentEL

+  ret

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
new file mode 100644
index 0000000..8fd4194
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
@@ -0,0 +1,127 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#include <AsmMacroIoLibV8.h>

+

+.text

+.align 3

+

+GCC_ASM_EXPORT (ArmIsMpCore)

+GCC_ASM_EXPORT (ArmEnableAsynchronousAbort)

+GCC_ASM_EXPORT (ArmDisableAsynchronousAbort)

+GCC_ASM_EXPORT (ArmEnableIrq)

+GCC_ASM_EXPORT (ArmDisableIrq)

+GCC_ASM_EXPORT (ArmEnableFiq)

+GCC_ASM_EXPORT (ArmDisableFiq)

+GCC_ASM_EXPORT (ArmEnableInterrupts)

+GCC_ASM_EXPORT (ArmDisableInterrupts)

+GCC_ASM_EXPORT (ArmDisableAllExceptions)

+GCC_ASM_EXPORT (ReadCCSIDR)

+GCC_ASM_EXPORT (ReadCLIDR)

+

+#------------------------------------------------------------------------------

+

+.set MPIDR_U_BIT,    (30)

+.set MPIDR_U_MASK,   (1 << MPIDR_U_BIT)

+.set DAIF_FIQ_BIT,   (1 << 0)

+.set DAIF_IRQ_BIT,   (1 << 1)

+.set DAIF_ABORT_BIT, (1 << 2)

+.set DAIF_DEBUG_BIT, (1 << 3)

+.set DAIF_INT_BITS,  (DAIF_FIQ_BIT | DAIF_IRQ_BIT)

+.set DAIF_ALL,       (DAIF_DEBUG_BIT | DAIF_ABORT_BIT | DAIF_INT_BITS)

+

+

+ASM_PFX(ArmIsMpCore):

+  mrs   x0, mpidr_el1         // Read EL1 Mutliprocessor Affinty Reg (MPIDR)

+  and   x0, x0, #MPIDR_U_MASK // U Bit clear, the processor is part of a multiprocessor system

+  lsr   x0, x0, #MPIDR_U_BIT

+  eor   x0, x0, #1

+  ret

+

+

+ASM_PFX(ArmEnableAsynchronousAbort):

+  msr   daifclr, #DAIF_ABORT_BIT

+  isb

+  ret

+

+

+ASM_PFX(ArmDisableAsynchronousAbort):

+  msr   daifset, #DAIF_ABORT_BIT

+  isb

+  ret

+

+

+ASM_PFX(ArmEnableIrq):

+  msr   daifclr, #DAIF_IRQ_BIT

+  isb

+  ret

+

+

+ASM_PFX(ArmDisableIrq):

+  msr   daifset, #DAIF_IRQ_BIT

+  isb

+  ret

+

+

+ASM_PFX(ArmEnableFiq):

+  msr   daifclr, #DAIF_FIQ_BIT

+  isb

+  ret

+

+

+ASM_PFX(ArmDisableFiq):

+  msr   daifset, #DAIF_FIQ_BIT

+  isb

+  ret

+

+

+ASM_PFX(ArmEnableInterrupts):

+  msr   daifclr, #DAIF_INT_BITS

+  isb

+  ret

+

+

+ASM_PFX(ArmDisableInterrupts):

+  msr   daifset, #DAIF_INT_BITS

+  isb

+  ret

+

+

+ASM_PFX(ArmDisableAllExceptions):

+  msr   daifset, #DAIF_ALL

+  isb

+  ret

+

+

+// UINT32

+// ReadCCSIDR (

+//   IN UINT32 CSSELR

+//   )

+ASM_PFX(ReadCCSIDR):

+  msr   csselr_el1, x0        // Write Cache Size Selection Register (CSSELR)

+  isb

+  mrs   x0, ccsidr_el1        // Read current Cache Size ID Register (CCSIDR)

+  ret

+

+

+// UINT32

+// ReadCLIDR (

+//   IN UINT32 CSSELR

+//   )

+ASM_PFX(ReadCLIDR):

+  mrs   x0, clidr_el1         // Read Cache Level ID Register

+  ret

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c
new file mode 100644
index 0000000..8c54b6c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c
@@ -0,0 +1,49 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Chipset/ARM1176JZ-S.h>

+

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+VOID

+EFIAPI

+ArmWriteVBar (

+  IN  UINTN   VectorBase

+  )

+{

+  ASSERT(FeaturePcdGet (PcdRelocateVectorTable) == TRUE);

+

+  if (VectorBase == 0x0) {

+    ArmSetLowVectors ();

+  } else if (VectorBase == 0xFFFF0000) {

+    ArmSetHighVectors ();

+  } else {

+    // Feature not supported by ARM11. The Vector Table is either at 0x0 or 0xFFFF0000

+    ASSERT(0);

+  }

+}

+

+UINTN

+EFIAPI

+ArmReadVBar (

+  VOID

+  )

+{

+  ASSERT((FeaturePcdGet (PcdRelocateVectorTable) == TRUE) && ((PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) || (PcdGet32 (PcdCpuVectorBaseAddress) == 0xFFFF0000)));

+  return PcdGet32 (PcdCpuVectorBaseAddress);

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf
new file mode 100644
index 0000000..32d9299
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf
@@ -0,0 +1,51 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Arm11ArmLib

+  FILE_GUID                      = 00586300-0E06-4790-AC44-86C56ACBB942

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  Arm11Support.S    | GCC

+  Arm11Support.asm  | RVCT

+

+  Arm11Lib.c

+  Arm11LibMem.c

+  ../Arm9/Arm9CacheInformation.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  MemoryAllocationLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FeaturePcd]

+  gArmTokenSpaceGuid.PcdRelocateVectorTable

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibMem.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibMem.c
new file mode 100644
index 0000000..0f89801
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibMem.c
@@ -0,0 +1,135 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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 <Chipset/ARM1176JZ-S.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+

+VOID

+FillTranslationTable (

+  IN  UINT32                        *TranslationTable,

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion

+  )

+{

+  UINT32  *Entry;

+  UINTN   Sections;

+  UINTN   Index;

+  UINT32  Attributes;

+  UINT32  PhysicalBase = MemoryRegion->PhysicalBase;

+

+  switch (MemoryRegion->Attributes) {

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);

+      break;

+    default:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);

+      break;

+  }

+

+  Entry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);

+  Sections = ((( MemoryRegion->Length - 1 ) / TT_DESCRIPTOR_SECTION_SIZE ) + 1 );

+

+  for (Index = 0; Index < Sections; Index++)

+  {

+    *Entry++     =  TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;

+    PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;

+  }

+}

+

+RETURN_STATUS

+EFIAPI

+ArmConfigureMmu (

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,

+  OUT VOID                         **TranslationTableBase OPTIONAL,

+  OUT UINTN                         *TranslationTableSize OPTIONAL

+  )

+{

+  VOID  *TranslationTable;

+

+  // Allocate pages for translation table.

+  TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT));

+  if (TranslationTable == NULL) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK);

+

+  if (TranslationTableBase != NULL) {

+    *TranslationTableBase = TranslationTable;

+  }

+

+  if (TranslationTableBase != NULL) {

+    *TranslationTableSize = TRANSLATION_TABLE_SIZE;

+  }

+

+  ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE);

+

+  ArmCleanInvalidateDataCache();

+  ArmInvalidateInstructionCache();

+  ArmInvalidateTlb();

+

+  ArmDisableDataCache();

+  ArmDisableInstructionCache();

+  ArmDisableMmu();

+

+  // Make sure nothing sneaked into the cache

+  ArmCleanInvalidateDataCache();

+  ArmInvalidateInstructionCache();

+

+  while (MemoryTable->Length != 0) {

+    FillTranslationTable(TranslationTable, MemoryTable);

+    MemoryTable++;

+  }

+

+  ArmSetTTBR0(TranslationTable);

+

+  ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |

+                            DOMAIN_ACCESS_CONTROL_NONE(14) |

+                            DOMAIN_ACCESS_CONTROL_NONE(13) |

+                            DOMAIN_ACCESS_CONTROL_NONE(12) |

+                            DOMAIN_ACCESS_CONTROL_NONE(11) |

+                            DOMAIN_ACCESS_CONTROL_NONE(10) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 9) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 8) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 7) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 6) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 5) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 4) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 3) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 2) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 1) |

+                            DOMAIN_ACCESS_CONTROL_MANAGER(0));

+

+  ArmEnableInstructionCache();

+  ArmEnableDataCache();

+  ArmEnableMmu();

+

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf
new file mode 100644
index 0000000..94dd03d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf
@@ -0,0 +1,51 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Arm11ArmLib

+  FILE_GUID                      = 8dfb4ea2-3901-44f9-ae54-ca3d50362d2f

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  Arm11Support.S    | GCC

+  Arm11Support.asm  | RVCT

+

+  Arm11Lib.c

+  Arm11LibMem.c

+  ../Arm9/Arm9CacheInformation.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PrePiLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FeaturePcd]

+  gArmTokenSpaceGuid.PcdRelocateVectorTable

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.inf
new file mode 100644
index 0000000..69763ed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.inf
@@ -0,0 +1,47 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Arm11LibSec

+  FILE_GUID                      = bfecdbc7-a860-4993-bc09-8e3ea762a758

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  Arm11Support.S    | GCC

+  Arm11Support.asm  | RVCT

+

+  Arm11Lib.c

+  ../Arm9/Arm9CacheInformation.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FeaturePcd]

+  gArmTokenSpaceGuid.PcdRelocateVectorTable

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S
new file mode 100644
index 0000000..25612f3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S
@@ -0,0 +1,257 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#include <AsmMacroIoLib.h>

+

+.text

+.align 2

+GCC_ASM_EXPORT(ArmDisableCachesAndMmu)

+GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)

+GCC_ASM_EXPORT(ArmCleanDataCache)

+GCC_ASM_EXPORT(ArmInvalidateDataCache)

+GCC_ASM_EXPORT(ArmInvalidateInstructionCache)

+GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)

+GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT(ArmEnableMmu)

+GCC_ASM_EXPORT(ArmDisableMmu)

+GCC_ASM_EXPORT(ArmMmuEnabled)

+GCC_ASM_EXPORT(ArmEnableDataCache)

+GCC_ASM_EXPORT(ArmDisableDataCache)

+GCC_ASM_EXPORT(ArmEnableInstructionCache)

+GCC_ASM_EXPORT(ArmDisableInstructionCache)

+GCC_ASM_EXPORT(ArmEnableBranchPrediction)

+GCC_ASM_EXPORT(ArmDisableBranchPrediction)

+GCC_ASM_EXPORT(ArmDataMemoryBarrier)

+GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)

+GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)

+GCC_ASM_EXPORT(ArmSetLowVectors)

+GCC_ASM_EXPORT(ArmSetHighVectors)

+GCC_ASM_EXPORT(ArmIsMpCore)

+GCC_ASM_EXPORT(ArmCallWFI)

+GCC_ASM_EXPORT(ArmReadMpidr)

+GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)

+GCC_ASM_EXPORT(ArmEnableFiq)

+GCC_ASM_EXPORT(ArmDisableFiq)

+GCC_ASM_EXPORT(ArmEnableInterrupts)

+GCC_ASM_EXPORT(ArmDisableInterrupts)

+GCC_ASM_EXPORT (ArmEnableVFP)

+

+Arm11PartNumberMask:  .word       0xFFF0

+Arm11PartNumber:      .word       0xB020

+

+.set DC_ON, (0x1<<2)

+.set IC_ON, (0x1<<12)

+.set XP_ON, (0x1<<23)

+.set CTRL_M_BIT,  (1 << 0)

+.set CTRL_C_BIT,  (1 << 2)

+.set CTRL_I_BIT,  (1 << 12)

+

+ASM_PFX(ArmDisableCachesAndMmu):

+  mrc   p15, 0, r0, c1, c0, 0           @ Get control register

+  bic   r0, r0, #CTRL_M_BIT             @ Disable MMU

+  bic   r0, r0, #CTRL_C_BIT             @ Disable D Cache

+  bic   r0, r0, #CTRL_I_BIT             @ Disable I Cache

+  mcr   p15, 0, r0, c1, c0, 0           @ Write control register

+  bx      LR

+

+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c6, 1   @invalidate single data cache line

+  bx      lr

+

+

+ASM_PFX(ArmCleanDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c10, 1  @clean single data cache line

+  bx      lr

+

+

+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c14, 1  @clean and invalidate single data cache line

+  bx      lr

+

+

+ASM_PFX(ArmCleanDataCache):

+  mcr     p15, 0, r0, c7, c10, 0  @ clean entire data cache

+  bx      lr

+

+

+ASM_PFX(ArmCleanInvalidateDataCache):

+  mcr     p15, 0, r0, c7, c14, 0  @ clean and invalidate entire data cache

+  bx      lr

+

+

+ASM_PFX(ArmInvalidateDataCache):

+  mcr     p15, 0, r0, c7, c6, 0  @ invalidate entire data cache

+  bx      lr

+

+

+ASM_PFX(ArmInvalidateInstructionCache):

+  mcr     p15, 0, r0, c7, c5, 0  @invalidate entire instruction cache

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c5,4       @Flush Prefetch buffer

+  bx      lr

+

+ASM_PFX(ArmEnableMmu):

+  mrc     p15,0,R0,c1,c0,0

+  orr     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  bx      LR

+

+ASM_PFX(ArmMmuEnabled):

+  mrc     p15,0,R0,c1,c0,0

+  and     R0,R0,#1

+  bx      LR

+

+ASM_PFX(ArmDisableMmu):

+  mrc     p15,0,R0,c1,c0,0

+  bic     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4     @Data synchronization barrier

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c5,4      @Flush Prefetch buffer

+  bx      LR

+

+ASM_PFX(ArmEnableDataCache):

+  LoadConstantToReg(DC_ON, R1)  @ldr     R1,=DC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  orr     R0,R0,R1              @Set C bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  bx      LR

+

+ASM_PFX(ArmDisableDataCache):

+  LoadConstantToReg(DC_ON, R1)  @ldr     R1,=DC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  bic     R0,R0,R1              @Clear C bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  bx      LR

+

+ASM_PFX(ArmEnableInstructionCache):

+  ldr     R1,=IC_ON

+  mrc     p15,0,R0,c1,c0,0     @Read control register configuration data

+  orr     R0,R0,R1             @Set I bit

+  mcr     p15,0,r0,c1,c0,0     @Write control register configuration data

+  bx      LR

+

+ASM_PFX(ArmDisableInstructionCache):

+  ldr     R1,=IC_ON

+  mrc     p15,0,R0,c1,c0,0     @Read control register configuration data

+  bic     R0,R0,R1             @Clear I bit.

+  mcr     p15,0,r0,c1,c0,0     @Write control register configuration data

+  bx      LR

+

+ASM_PFX(ArmEnableBranchPrediction):

+  mrc     p15, 0, r0, c1, c0, 0

+  orr     r0, r0, #0x00000800

+  mcr     p15, 0, r0, c1, c0, 0

+  bx      LR

+

+ASM_PFX(ArmDisableBranchPrediction):

+  mrc     p15, 0, r0, c1, c0, 0

+  bic     r0, r0, #0x00000800

+  mcr     p15, 0, r0, c1, c0, 0

+  bx      LR

+

+ASM_PFX(ArmDataMemoryBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #5

+  bx      LR

+

+ASM_PFX(ArmDataSyncronizationBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #4

+  bx      LR

+

+ASM_PFX(ArmInstructionSynchronizationBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C5, #4

+  bx      LR

+

+ASM_PFX(ArmSetLowVectors):

+  mrc     p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)

+  bic     r0, r0, #0x00002000   @ clear V bit

+  mcr     p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)

+  bx      LR

+

+ASM_PFX(ArmSetHighVectors):

+  mrc     p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)

+  orr     r0, r0, #0x00002000   @ clear V bit

+  mcr     p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)

+  bx      LR

+

+ASM_PFX(ArmIsMpCore):

+  push    { r1 }

+  mrc     p15, 0, r0, c0, c0, 0

+  # Extract Part Number to check it is an ARM11MP core (0xB02)

+  LoadConstantToReg (Arm11PartNumberMask, r1)

+  and     r0, r0, r1

+  LoadConstantToReg (Arm11PartNumber, r1)

+  cmp     r0, r1

+  movne   r0, #0

+  pop     { r1 }

+  bx      lr

+

+ASM_PFX(ArmCallWFI):

+  wfi

+  bx      lr

+

+ASM_PFX(ArmReadMpidr):

+  mrc     p15, 0, r0, c0, c0, 5       @ read MPIDR

+  bx      lr

+

+ASM_PFX(ArmEnableFiq):

+  mrs     R0,CPSR

+  bic     R0,R0,#0x40    @Enable FIQ interrupts

+  msr     CPSR_c,R0

+  bx      LR

+

+ASM_PFX(ArmDisableFiq):

+  mrs     R0,CPSR

+  orr     R1,R0,#0x40    @Disable FIQ interrupts

+  msr     CPSR_c,R1

+  tst     R0,#0x80

+  moveq   R0,#1

+  movne   R0,#0

+  bx      LR

+

+ASM_PFX(ArmEnableInterrupts):

+  mrs     R0,CPSR

+  bic     R0,R0,#0x80    @Enable IRQ interrupts

+  msr     CPSR_c,R0

+  bx      LR

+

+ASM_PFX(ArmDisableInterrupts):

+  mrs     R0,CPSR

+  orr     R1,R0,#0x80    @Disable IRQ interrupts

+  msr     CPSR_c,R1

+  tst     R0,#0x80

+  moveq   R0,#1

+  movne   R0,#0

+  bx      LR

+

+ASM_PFX(ArmEnableVFP):

+  # Read CPACR (Coprocessor Access Control Register)

+  mrc     p15, 0, r0, c1, c0, 2

+  # Enable VPF access (Full Access to CP10, CP11) (V* instructions)

+  orr     r0, r0, #0x00f00000

+  # Write back CPACR (Coprocessor Access Control Register)

+  mcr     p15, 0, r0, c1, c0, 2

+  # Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.

+  mov     r0, #0x40000000

+  #TODO: Fixme - need compilation flag

+  #fmxr    FPEXC, r0

+  bx      lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm
new file mode 100644
index 0000000..53283d1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm
@@ -0,0 +1,157 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+    EXPORT  ArmCleanInvalidateDataCache

+    EXPORT  ArmCleanDataCache

+    EXPORT  ArmInvalidateDataCache

+    EXPORT  ArmInvalidateInstructionCache

+    EXPORT  ArmInvalidateDataCacheEntryByMVA

+    EXPORT  ArmCleanDataCacheEntryByMVA

+    EXPORT  ArmCleanInvalidateDataCacheEntryByMVA

+    EXPORT  ArmEnableMmu

+    EXPORT  ArmDisableMmu

+    EXPORT  ArmMmuEnabled

+    EXPORT  ArmEnableDataCache

+    EXPORT  ArmDisableDataCache

+    EXPORT  ArmEnableInstructionCache

+    EXPORT  ArmDisableInstructionCache

+    EXPORT  ArmEnableBranchPrediction

+    EXPORT  ArmDisableBranchPrediction

+    EXPORT  ArmDataMemoryBarrier

+    EXPORT  ArmDataSyncronizationBarrier

+    EXPORT  ArmInstructionSynchronizationBarrier

+

+

+DC_ON       EQU     ( 0x1:SHL:2 )

+IC_ON       EQU     ( 0x1:SHL:12 )

+XP_ON       EQU     ( 0x1:SHL:23 )

+

+

+    AREA    ArmCacheLib, CODE, READONLY

+    PRESERVE8

+

+

+ArmInvalidateDataCacheEntryByMVA

+  mcr     p15, 0, r0, c7, c6, 1   ; invalidate single data cache line

+  bx      lr

+

+

+ArmCleanDataCacheEntryByMVA

+  mcr     p15, 0, r0, c7, c10, 1  ; clean single data cache line

+  bx      lr

+

+

+ArmCleanInvalidateDataCacheEntryByMVA

+  mcr     p15, 0, r0, c7, c14, 1  ; clean and invalidate single data cache line

+  bx      lr

+

+

+ArmCleanDataCache

+  mcr     p15, 0, r0, c7, c10, 0  ; clean entire data cache

+  bx      lr

+

+

+ArmCleanInvalidateDataCache

+  mcr     p15, 0, r0, c7, c14, 0  ; clean and invalidate entire data cache

+  bx      lr

+

+

+ArmInvalidateDataCache

+  mcr     p15, 0, r0, c7, c6, 0  ; invalidate entire data cache

+  bx      lr

+

+

+ArmInvalidateInstructionCache

+  mcr     p15, 0, r0, c7, c5, 0  ;invalidate entire instruction cache

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c5,4       ;Flush Prefetch buffer

+  bx      lr

+

+ArmEnableMmu

+  mrc     p15,0,R0,c1,c0,0

+  orr     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  bx      LR

+

+ArmMmuEnabled

+  mrc     p15,0,R0,c1,c0,0

+  and     R0,R0,#1

+  bx      LR

+

+ArmDisableMmu

+  mrc     p15,0,R0,c1,c0,0

+  bic     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4     ;Data synchronization barrier

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c5,4      ;Flush Prefetch buffer

+  bx      LR

+

+ArmEnableDataCache

+  LDR     R1,=DC_ON

+  MRC     p15,0,R0,c1,c0,0      ;Read control register configuration data

+  ORR     R0,R0,R1              ;Set C bit

+  MCR     p15,0,r0,c1,c0,0      ;Write control register configuration data

+  BX      LR

+

+ArmDisableDataCache

+  LDR     R1,=DC_ON

+  MRC     p15,0,R0,c1,c0,0      ;Read control register configuration data

+  BIC     R0,R0,R1              ;Clear C bit

+  MCR     p15,0,r0,c1,c0,0      ;Write control register configuration data

+  BX      LR

+

+ArmEnableInstructionCache

+  LDR     R1,=IC_ON

+  MRC     p15,0,R0,c1,c0,0     ;Read control register configuration data

+  ORR     R0,R0,R1             ;Set I bit

+  MCR     p15,0,r0,c1,c0,0     ;Write control register configuration data

+  BX      LR

+

+ArmDisableInstructionCache

+  LDR     R1,=IC_ON

+  MRC     p15,0,R0,c1,c0,0     ;Read control register configuration data

+  BIC     R0,R0,R1             ;Clear I bit.

+  MCR     p15,0,r0,c1,c0,0     ;Write control register configuration data

+  BX      LR

+

+ArmEnableBranchPrediction

+  mrc     p15, 0, r0, c1, c0, 0

+  orr     r0, r0, #0x00000800

+  mcr     p15, 0, r0, c1, c0, 0

+  bx      LR

+

+ArmDisableBranchPrediction

+  mrc     p15, 0, r0, c1, c0, 0

+  bic     r0, r0, #0x00000800

+  mcr     p15, 0, r0, c1, c0, 0

+  bx      LR

+

+ASM_PFX(ArmDataMemoryBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #5

+  bx      LR

+

+ASM_PFX(ArmDataSyncronizationBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #4

+  bx      LR

+

+ASM_PFX(ArmInstructionSynchronizationBarrier):

+  MOV R0, #0

+  MCR P15, #0, R0, C7, C5, #4

+  bx      LR

+

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
new file mode 100644
index 0000000..81661b2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
@@ -0,0 +1,46 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Arm9ArmLib

+  FILE_GUID                      = 375D70D3-91E0-4374-A540-68BD959EB184

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  Arm9Support.S    | GCC

+  Arm9Support.asm  | RVCT

+

+  Arm9Lib.c

+  Arm9CacheInformation.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  MemoryAllocationLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
new file mode 100644
index 0000000..0730487
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
@@ -0,0 +1,46 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Arm9ArmLibPrePi

+  FILE_GUID                      = e9b6011f-ee15-4e59-ab8f-a819a081fa54

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  Arm9Support.S    | GCC

+  Arm9Support.asm  | RVCT

+

+  Arm9Lib.c

+  Arm9CacheInformation.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PrePiLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
new file mode 100644
index 0000000..f0b5060
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
@@ -0,0 +1,165 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2014, ARM Limited. All rights reserved.

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Library/ArmLib.h>

+#include "ArmLibPrivate.h"

+

+ARM_CACHE_TYPE

+EFIAPI

+ArmCacheType (

+  VOID

+  )

+{

+  switch (CACHE_TYPE (ArmCacheInfo ()))

+  {

+    case CACHE_TYPE_WRITE_BACK: return ARM_CACHE_TYPE_WRITE_BACK;

+    default:                    return ARM_CACHE_TYPE_UNKNOWN;

+  }

+}

+

+ARM_CACHE_ARCHITECTURE

+EFIAPI

+ArmCacheArchitecture (

+  VOID

+  )

+{

+  switch (CACHE_ARCHITECTURE (ArmCacheInfo ()))

+  {

+    case CACHE_ARCHITECTURE_UNIFIED:  return ARM_CACHE_ARCHITECTURE_UNIFIED;

+    case CACHE_ARCHITECTURE_SEPARATE: return ARM_CACHE_ARCHITECTURE_SEPARATE;

+    default:                          return ARM_CACHE_ARCHITECTURE_UNKNOWN;

+  }

+}

+

+BOOLEAN

+EFIAPI

+ArmDataCachePresent (

+  VOID

+  )

+{

+  switch (DATA_CACHE_PRESENT (ArmCacheInfo ()))

+  {

+    case CACHE_PRESENT:     return TRUE;

+    case CACHE_NOT_PRESENT: return FALSE;

+    default:                return FALSE;

+  }

+}

+

+UINTN

+EFIAPI

+ArmDataCacheSize (

+  VOID

+  )

+{

+  switch (DATA_CACHE_SIZE (ArmCacheInfo ()))

+  {

+    case CACHE_SIZE_4_KB:   return   4 * 1024;

+    case CACHE_SIZE_8_KB:   return   8 * 1024;

+    case CACHE_SIZE_16_KB:  return  16 * 1024;

+    case CACHE_SIZE_32_KB:  return  32 * 1024;

+    case CACHE_SIZE_64_KB:  return  64 * 1024;

+    case CACHE_SIZE_128_KB: return 128 * 1024;

+    default:                return   0;

+  }

+}

+

+UINTN

+EFIAPI

+ArmDataCacheAssociativity (

+  VOID

+  )

+{

+  switch (DATA_CACHE_ASSOCIATIVITY (ArmCacheInfo ()))

+  {

+    case CACHE_ASSOCIATIVITY_4_WAY:   return 4;

+    case CACHE_ASSOCIATIVITY_DIRECT:  return 1;

+    default:                          return 0;

+  }

+}

+

+UINTN

+EFIAPI

+ArmDataCacheLineLength (

+  VOID

+  )

+{

+  switch (DATA_CACHE_LINE_LENGTH (ArmCacheInfo ()))

+  {

+    case CACHE_LINE_LENGTH_32_BYTES: return 32;

+    default:                         return  0;

+  }

+}

+

+BOOLEAN

+EFIAPI

+ArmInstructionCachePresent (

+  VOID

+  )

+{

+  switch (INSTRUCTION_CACHE_PRESENT (ArmCacheInfo ()))

+  {

+    case CACHE_PRESENT:     return TRUE;

+    case CACHE_NOT_PRESENT: return FALSE;

+    default:                return FALSE;

+  }

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheSize (

+  VOID

+  )

+{

+  switch (INSTRUCTION_CACHE_SIZE (ArmCacheInfo ()))

+  {

+    case CACHE_SIZE_4_KB:   return   4 * 1024;

+    case CACHE_SIZE_8_KB:   return   8 * 1024;

+    case CACHE_SIZE_16_KB:  return  16 * 1024;

+    case CACHE_SIZE_32_KB:  return  32 * 1024;

+    case CACHE_SIZE_64_KB:  return  64 * 1024;

+    case CACHE_SIZE_128_KB: return 128 * 1024;

+    default:                return   0;

+  }

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheAssociativity (

+  VOID

+  )

+{

+  switch (INSTRUCTION_CACHE_ASSOCIATIVITY (ArmCacheInfo ()))

+  {

+    case CACHE_ASSOCIATIVITY_8_WAY:   return 8;

+    case CACHE_ASSOCIATIVITY_4_WAY:   return 4;

+    case CACHE_ASSOCIATIVITY_DIRECT:  return 1;

+    default:                          return 0;

+  }

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheLineLength (

+  VOID

+  )

+{

+  switch (INSTRUCTION_CACHE_LINE_LENGTH (ArmCacheInfo ()))

+  {

+    case CACHE_LINE_LENGTH_32_BYTES: return 32;

+    default:                         return  0;

+  }

+}

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c
new file mode 100644
index 0000000..7432f7b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c
@@ -0,0 +1,134 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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 <Chipset/ARM926EJ-S.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/DebugLib.h>

+

+VOID

+FillTranslationTable (

+  IN  UINT32                        *TranslationTable,

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion

+  )

+{

+  UINT32  *Entry;

+  UINTN   Sections;

+  UINTN   Index;

+  UINT32  Attributes;

+  UINT32  PhysicalBase = MemoryRegion->PhysicalBase;

+

+  switch (MemoryRegion->Attributes) {

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:

+      ASSERT(0); // Trustzone is not supported on ARMv5

+    default:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;

+      break;

+  }

+

+  Entry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);

+  Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;

+

+  // The current code does not support memory region size that is not aligned on TT_DESCRIPTOR_SECTION_SIZE boundary

+  ASSERT (MemoryRegion->Length % TT_DESCRIPTOR_SECTION_SIZE == 0);

+

+  for (Index = 0; Index < Sections; Index++)

+  {

+    *Entry++     =  TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;

+    PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;

+  }

+}

+

+RETURN_STATUS

+EFIAPI

+ArmConfigureMmu (

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,

+  OUT VOID                         **TranslationTableBase OPTIONAL,

+  OUT UINTN                         *TranslationTableSize OPTIONAL

+  )

+{

+  VOID  *TranslationTable;

+

+  // Allocate pages for translation table.

+  TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT));

+  if (TranslationTable == NULL) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK);

+

+  if (TranslationTableBase != NULL) {

+    *TranslationTableBase = TranslationTable;

+  }

+

+  if (TranslationTableBase != NULL) {

+    *TranslationTableSize = TRANSLATION_TABLE_SIZE;

+  }

+

+  ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE);

+

+  ArmCleanInvalidateDataCache();

+  ArmInvalidateInstructionCache();

+  ArmInvalidateTlb();

+

+  ArmDisableDataCache();

+  ArmDisableInstructionCache();

+  ArmDisableMmu();

+

+  // Make sure nothing sneaked into the cache

+  ArmCleanInvalidateDataCache();

+  ArmInvalidateInstructionCache();

+

+  while (MemoryTable->Length != 0) {

+    FillTranslationTable(TranslationTable, MemoryTable);

+    MemoryTable++;

+  }

+

+  ArmSetTTBR0(TranslationTable);

+

+  ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |

+                            DOMAIN_ACCESS_CONTROL_NONE(14) |

+                            DOMAIN_ACCESS_CONTROL_NONE(13) |

+                            DOMAIN_ACCESS_CONTROL_NONE(12) |

+                            DOMAIN_ACCESS_CONTROL_NONE(11) |

+                            DOMAIN_ACCESS_CONTROL_NONE(10) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 9) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 8) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 7) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 6) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 5) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 4) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 3) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 2) |

+                            DOMAIN_ACCESS_CONTROL_NONE( 1) |

+                            DOMAIN_ACCESS_CONTROL_MANAGER(0));

+

+  ArmEnableInstructionCache();

+  ArmEnableDataCache();

+  ArmEnableMmu();

+

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S
new file mode 100644
index 0000000..c708d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S
@@ -0,0 +1,153 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)

+GCC_ASM_EXPORT(ArmCleanDataCache)

+GCC_ASM_EXPORT(ArmInvalidateDataCache)

+GCC_ASM_EXPORT(ArmInvalidateInstructionCache)

+GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)

+GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT(ArmEnableMmu)

+GCC_ASM_EXPORT(ArmDisableMmu)

+GCC_ASM_EXPORT(ArmMmuEnabled)

+GCC_ASM_EXPORT(ArmEnableDataCache)

+GCC_ASM_EXPORT(ArmDisableDataCache)

+GCC_ASM_EXPORT(ArmEnableInstructionCache)

+GCC_ASM_EXPORT(ArmDisableInstructionCache)

+GCC_ASM_EXPORT(ArmEnableBranchPrediction)

+GCC_ASM_EXPORT(ArmDisableBranchPrediction)

+GCC_ASM_EXPORT(ArmDataMemoryBarrier)

+GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)

+GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)

+

+

+.set DC_ON, (1<<2)

+.set IC_ON, (1<<12)

+

+#------------------------------------------------------------------------------

+

+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c6, 1   @ invalidate single data cache line

+  bx      lr

+

+ASM_PFX(ArmCleanDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c10, 1  @ clean single data cache line

+  bx      lr

+

+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c14, 1  @ clean and invalidate single data cache line

+  bx      lr

+

+ASM_PFX(ArmEnableInstructionCache):

+  ldr    r1,=IC_ON

+  mrc    p15,0,r0,c1,c0,0     @Read control register configuration data

+  orr    r0,r0,r1             @Set I bit

+  mcr    p15,0,r0,c1,c0,0     @Write control register configuration data

+  bx     LR

+

+ASM_PFX(ArmDisableInstructionCache):

+  ldr    r1,=IC_ON

+  mrc    p15,0,r0,c1,c0,0     @Read control register configuration data

+  bic    r0,r0,r1             @Clear I bit.

+  mcr    p15,0,r0,c1,c0,0     @Write control register configuration data

+  bx     LR

+

+ASM_PFX(ArmInvalidateInstructionCache):

+  mov     r0,#0

+  mcr     p15,0,r0,c7,c5,0     @Invalidate entire Instruction cache.

+                         @Also flushes the branch target cache.

+  mov     r0,#0

+  mcr     p15,0,r0,c7,c10,4    @Data write buffer

+  bx      LR

+

+ASM_PFX(ArmEnableMmu):

+  mrc     p15,0,R0,c1,c0,0

+  orr     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  bx      LR

+

+ASM_PFX(ArmMmuEnabled):

+  mrc     p15,0,R0,c1,c0,0

+  and     R0,R0,#1

+  bx      LR

+

+ASM_PFX(ArmDisableMmu):

+  mrc     p15,0,R0,c1,c0,0

+  bic     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4     @Drain write buffer

+  bx      LR

+

+ASM_PFX(ArmEnableDataCache):

+  ldr     R1,=DC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  orr     R0,R0,R1              @Set C bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  bx      LR

+

+ASM_PFX(ArmDisableDataCache):

+  ldr     R1,=DC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  bic     R0,R0,R1              @Clear C bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  bx      LR

+

+ASM_PFX(ArmCleanDataCache):

+  mrc     p15,0,r15,c7,c10,3

+  bne     ASM_PFX(ArmCleanDataCache)

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4  @Drain write buffer

+  bx      LR

+

+ASM_PFX(ArmInvalidateDataCache):

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c6,0        @Invalidate entire data cache

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4       @Drain write buffer

+  bx      LR

+

+ASM_PFX(ArmCleanInvalidateDataCache):

+  mrc     p15,0,r15,c7,c14,3

+  bne     ASM_PFX(ArmCleanInvalidateDataCache)

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4        @Drain write buffer

+  bx      LR

+

+ASM_PFX(ArmEnableBranchPrediction):

+  bx      LR                      @Branch prediction is not supported.

+

+ASM_PFX(ArmDisableBranchPrediction):

+  bx      LR                      @Branch prediction is not supported.

+

+ASM_PFX(ArmDataMemoryBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #5    @ check if this is OK?

+  bx      LR

+

+ASM_PFX(ArmDataSyncronizationBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #4   @ check if this is OK?

+  bx      LR

+

+ASM_PFX(ArmInstructionSynchronizationBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C5, #4     @ check if this is OK?

+  bx      LR

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm
new file mode 100644
index 0000000..4aaa546
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm
@@ -0,0 +1,153 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+    EXPORT  ArmCleanInvalidateDataCache

+    EXPORT  ArmCleanDataCache

+    EXPORT  ArmInvalidateDataCache

+    EXPORT  ArmInvalidateInstructionCache

+    EXPORT  ArmInvalidateDataCacheEntryByMVA

+    EXPORT  ArmCleanDataCacheEntryByMVA

+    EXPORT  ArmCleanInvalidateDataCacheEntryByMVA

+    EXPORT  ArmEnableMmu

+    EXPORT  ArmDisableMmu

+    EXPORT  ArmMmuEnabled

+    EXPORT  ArmEnableDataCache

+    EXPORT  ArmDisableDataCache

+    EXPORT  ArmEnableInstructionCache

+    EXPORT  ArmDisableInstructionCache

+    EXPORT  ArmEnableBranchPrediction

+    EXPORT  ArmDisableBranchPrediction

+    EXPORT  ArmDataMemoryBarrier

+    EXPORT  ArmDataSyncronizationBarrier

+    EXPORT  ArmInstructionSynchronizationBarrier

+

+

+DC_ON       EQU     ( 0x1:SHL:2 )

+IC_ON       EQU     ( 0x1:SHL:12 )

+

+    AREA    ArmCacheLib, CODE, READONLY

+    PRESERVE8

+

+

+ArmInvalidateDataCacheEntryByMVA

+  MCR     p15, 0, r0, c7, c6, 1   ; invalidate single data cache line

+  BX      lr

+

+

+ArmCleanDataCacheEntryByMVA

+  MCR     p15, 0, r0, c7, c10, 1  ; clean single data cache line

+  BX      lr

+

+

+ArmCleanInvalidateDataCacheEntryByMVA

+  MCR     p15, 0, r0, c7, c14, 1  ; clean and invalidate single data cache line

+  BX      lr

+

+ArmEnableInstructionCache

+  LDR     R1,=IC_ON

+  MRC     p15,0,R0,c1,c0,0     ;Read control register configuration data

+  ORR     R0,R0,R1             ;Set I bit

+  MCR     p15,0,r0,c1,c0,0     ;Write control register configuration data

+  BX      LR

+

+ArmDisableInstructionCache

+  LDR     R1,=IC_ON

+  MRC     p15,0,R0,c1,c0,0     ;Read control register configuration data

+  BIC     R0,R0,R1             ;Clear I bit.

+  MCR     p15,0,r0,c1,c0,0     ;Write control register configuration data

+  BX      LR

+

+ArmInvalidateInstructionCache

+  MOV     R0,#0

+  MCR     p15,0,R0,c7,c5,0      ;Invalidate entire instruction cache

+  MOV     R0,#0

+  MCR     p15,0,R0,c7,c10,4     ;Drain write buffer

+  BX      LR

+

+ArmEnableMmu

+  mrc     p15,0,R0,c1,c0,0

+  orr     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  bx      LR

+

+ArmMmuEnabled

+  mrc     p15,0,R0,c1,c0,0

+  and     R0,R0,#1

+  bx      LR

+

+ArmDisableMmu

+  mrc     p15,0,R0,c1,c0,0

+  bic     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  mov     R0,#0

+  mcr     p15,0,R0,c7,c10,4     ;Drain write buffer

+  bx      LR

+

+ArmEnableDataCache

+  LDR     R1,=DC_ON

+  MRC     p15,0,R0,c1,c0,0      ;Read control register configuration data

+  ORR     R0,R0,R1              ;Set C bit

+  MCR     p15,0,r0,c1,c0,0      ;Write control register configuration data

+  BX      LR

+

+ArmDisableDataCache

+  LDR     R1,=DC_ON

+  MRC     p15,0,R0,c1,c0,0      ;Read control register configuration data

+  BIC     R0,R0,R1              ;Clear C bit

+  MCR     p15,0,r0,c1,c0,0      ;Write control register configuration data

+  BX      LR

+

+ArmCleanDataCache

+  MRC     p15,0,r15,c7,c10,3

+  BNE     ArmCleanDataCache

+  MOV     R0,#0

+  MCR     p15,0,R0,c7,c10,4      ;Drain write buffer

+  BX      LR

+

+ArmInvalidateDataCache

+  MOV     R0,#0

+  MCR     p15,0,R0,c7,c6,0      ;Invalidate entire data cache

+  MOV     R0,#0

+  MCR     p15,0,R0,c7,c10,4     ;Drain write buffer

+  BX      LR

+

+ArmCleanInvalidateDataCache

+  MRC     p15,0,r15,c7,c14,3

+  BNE     ArmCleanInvalidateDataCache

+  MOV     R0,#0

+  MCR     p15,0,R0,c7,c10,4      ;Drain write buffer

+  BX      LR

+

+ArmEnableBranchPrediction

+  bx      LR                    ;Branch prediction is not supported.

+

+ArmDisableBranchPrediction

+  bx      LR                    ;Branch prediction is not supported.

+

+ASM_PFX(ArmDataMemoryBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #5  ; Check to see if this is correct

+  bx      LR

+

+ASM_PFX(ArmDataSyncronizationBarrier):

+  mov R0, #0

+  mcr P15, #0, R0, C7, C10, #4 ; Check to see if this is correct

+  bx      LR

+

+ASM_PFX(ArmInstructionSynchronizationBarrier):

+  MOV R0, #0

+  MCR P15, #0, R0, C7, C5, #4 ; Check to see if this is correct

+  bx      LR

+

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
new file mode 100644
index 0000000..b94239f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
@@ -0,0 +1,113 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# 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>

+

+.text

+.align 2

+

+GCC_ASM_EXPORT(ArmIsMpCore)

+GCC_ASM_EXPORT(ArmEnableAsynchronousAbort)

+GCC_ASM_EXPORT(ArmDisableAsynchronousAbort)

+GCC_ASM_EXPORT(ArmEnableIrq)

+GCC_ASM_EXPORT(ArmDisableIrq)

+GCC_ASM_EXPORT(ArmEnableFiq)

+GCC_ASM_EXPORT(ArmDisableFiq)

+GCC_ASM_EXPORT(ArmEnableInterrupts)

+GCC_ASM_EXPORT(ArmDisableInterrupts)

+GCC_ASM_EXPORT(ReadCCSIDR)

+GCC_ASM_EXPORT(ReadCLIDR)

+GCC_ASM_EXPORT(ArmReadNsacr)

+GCC_ASM_EXPORT(ArmWriteNsacr)

+

+#------------------------------------------------------------------------------

+

+ASM_PFX(ArmIsMpCore):

+  mrc     p15,0,R0,c0,c0,5

+  // Get Multiprocessing extension (bit31) & U bit (bit30)

+  and     R0, R0, #0xC0000000

+  // if (bit31 == 1) && (bit30 == 0) then the processor is part of a multiprocessor system

+  cmp     R0, #0x80000000

+  moveq   R0, #1

+  movne   R0, #0

+  bx      LR

+

+ASM_PFX(ArmEnableAsynchronousAbort):

+  cpsie   a

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableAsynchronousAbort):

+  cpsid   a

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableIrq):

+  cpsie   i

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableIrq):

+  cpsid   i

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableFiq):

+  cpsie   f

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableFiq):

+  cpsid   f

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableInterrupts):

+  cpsie   if

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableInterrupts):

+  cpsid   if

+  isb

+  bx      LR

+

+// UINT32

+// ReadCCSIDR (

+//   IN UINT32 CSSELR

+//   )

+ASM_PFX(ReadCCSIDR):

+  mcr p15,2,r0,c0,c0,0   @ Write Cache Size Selection Register (CSSELR)

+  isb

+  mrc p15,1,r0,c0,c0,0   @ Read current CP15 Cache Size ID Register (CCSIDR)

+  bx  lr

+

+// UINT32

+// ReadCLIDR (

+//   IN UINT32 CSSELR

+//   )

+ASM_PFX(ReadCLIDR):

+  mrc p15,1,r0,c0,c0,1 @ Read CP15 Cache Level ID Register

+  bx  lr

+

+ASM_PFX(ArmReadNsacr):

+  mrc     p15, 0, r0, c1, c1, 2

+  bx      lr

+

+ASM_PFX(ArmWriteNsacr):

+  mcr     p15, 0, r0, c1, c1, 2

+  bx      lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
new file mode 100644
index 0000000..82daa3c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
@@ -0,0 +1,112 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+// 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.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  ArmIsMpCore

+    EXPORT  ArmEnableAsynchronousAbort

+    EXPORT  ArmDisableAsynchronousAbort

+    EXPORT  ArmEnableIrq

+    EXPORT  ArmDisableIrq

+    EXPORT  ArmEnableFiq

+    EXPORT  ArmDisableFiq

+    EXPORT  ArmEnableInterrupts

+    EXPORT  ArmDisableInterrupts

+    EXPORT  ReadCCSIDR

+    EXPORT  ReadCLIDR

+    EXPORT  ArmReadNsacr

+    EXPORT  ArmWriteNsacr

+

+    AREA ArmLibSupportV7, CODE, READONLY

+

+

+//------------------------------------------------------------------------------

+

+ArmIsMpCore

+  mrc     p15,0,R0,c0,c0,5

+  // Get Multiprocessing extension (bit31) & U bit (bit30)

+  and     R0, R0, #0xC0000000

+  // if (bit31 == 1) && (bit30 == 0) then the processor is part of a multiprocessor system

+  cmp     R0, #0x80000000

+  moveq   R0, #1

+  movne   R0, #0

+  bx      LR

+

+ArmEnableAsynchronousAbort

+  cpsie   a

+  isb

+  bx      LR

+

+ArmDisableAsynchronousAbort

+  cpsid   a

+  isb

+  bx      LR

+

+ArmEnableIrq

+  cpsie   i

+  isb

+  bx      LR

+

+ArmDisableIrq

+  cpsid   i

+  isb

+  bx      LR

+

+ArmEnableFiq

+  cpsie   f

+  isb

+  bx      LR

+

+ArmDisableFiq

+  cpsid   f

+  isb

+  bx      LR

+

+ArmEnableInterrupts

+  cpsie   if

+  isb

+  bx      LR

+

+ArmDisableInterrupts

+  cpsid   if

+  isb

+  bx      LR

+

+// UINT32

+// ReadCCSIDR (

+//   IN UINT32 CSSELR

+//   )

+ReadCCSIDR

+  mcr p15,2,r0,c0,c0,0   ; Write Cache Size Selection Register (CSSELR)

+  isb

+  mrc p15,1,r0,c0,c0,0 ; Read current CP15 Cache Size ID Register (CCSIDR)

+  bx  lr

+

+// UINT32

+// ReadCLIDR (

+//   IN UINT32 CSSELR

+//   )

+ReadCLIDR

+  mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register

+  bx  lr

+

+ArmReadNsacr

+  mrc     p15, 0, r0, c1, c1, 2

+  bx      lr

+

+ArmWriteNsacr

+  mcr     p15, 0, r0, c1, c1, 2

+  bx      lr

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c
new file mode 100644
index 0000000..49be71b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c
@@ -0,0 +1,168 @@
+/** @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.

+*

+**/

+

+#include <Uefi.h>

+#include <Chipset/ArmV7.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include "ArmV7Lib.h"

+#include "ArmLibPrivate.h"

+#include <Library/ArmArchTimer.h>

+

+VOID

+EFIAPI

+ArmArchTimerReadReg (

+    IN   ARM_ARCH_TIMER_REGS   Reg,

+    OUT  VOID                  *DstBuf

+    )

+{

+  // Check if the Generic/Architecture timer is implemented

+  if (ArmIsArchTimerImplemented ()) {

+    switch (Reg) {

+    case CntFrq:

+      *((UINTN *)DstBuf) = ArmReadCntFrq ();

+      return;

+

+    case CntPct:

+      *((UINT64 *)DstBuf) = ArmReadCntPct ();

+      return;

+

+    case CntkCtl:

+      *((UINTN *)DstBuf) = ArmReadCntkCtl();

+      return;

+

+    case CntpTval:

+      *((UINTN *)DstBuf) = ArmReadCntpTval ();

+      return;

+

+    case CntpCtl:

+      *((UINTN *)DstBuf) = ArmReadCntpCtl ();

+      return;

+

+    case CntvTval:

+      *((UINTN *)DstBuf) = ArmReadCntvTval ();

+      return;

+

+    case CntvCtl:

+      *((UINTN *)DstBuf) = ArmReadCntvCtl ();

+      return;

+

+    case CntvCt:

+      *((UINT64 *)DstBuf) = ArmReadCntvCt ();

+      return;

+

+    case CntpCval:

+      *((UINT64 *)DstBuf) = ArmReadCntpCval ();

+      return;

+

+    case CntvCval:

+      *((UINT64 *)DstBuf) = ArmReadCntvCval ();

+      return;

+

+    case CntvOff:

+      *((UINT64 *)DstBuf) = ArmReadCntvOff ();

+      return;

+

+    case CnthCtl:

+    case CnthpTval:

+    case CnthpCtl:

+    case CnthpCval:

+      DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));

+      break;

+

+    default:

+      DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));

+    }

+  } else {

+    DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));

+    ASSERT (0);

+  }

+

+  *((UINT64 *)DstBuf) = 0;

+}

+

+VOID

+EFIAPI

+ArmArchTimerWriteReg (

+    IN   ARM_ARCH_TIMER_REGS   Reg,

+    IN   VOID                  *SrcBuf

+    )

+{

+  // Check if the Generic/Architecture timer is implemented

+  if (ArmIsArchTimerImplemented ()) {

+

+    switch (Reg) {

+

+    case CntFrq:

+      ArmWriteCntFrq (*((UINTN *)SrcBuf));

+      break;

+

+    case CntPct:

+      DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTPCT \n"));

+      break;

+

+    case CntkCtl:

+      ArmWriteCntkCtl (*((UINTN *)SrcBuf));

+      break;

+

+    case CntpTval:

+      ArmWriteCntpTval (*((UINTN *)SrcBuf));

+      break;

+

+    case CntpCtl:

+      ArmWriteCntpCtl (*((UINTN *)SrcBuf));

+      break;

+

+    case CntvTval:

+      ArmWriteCntvTval (*((UINTN *)SrcBuf));

+      break;

+

+    case CntvCtl:

+      ArmWriteCntvCtl (*((UINTN *)SrcBuf));

+      break;

+

+    case CntvCt:

+      DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTVCT \n"));

+      break;

+

+    case CntpCval:

+      ArmWriteCntpCval (*((UINT64 *)SrcBuf) );

+      break;

+

+    case CntvCval:

+      ArmWriteCntvCval (*((UINT64 *)SrcBuf) );

+      break;

+

+    case CntvOff:

+      ArmWriteCntvOff (*((UINT64 *)SrcBuf));

+      break;

+

+    case CnthCtl:

+    case CnthpTval:

+    case CnthpCtl:

+    case CnthpCval:

+      DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));

+      break;

+

+    default:

+      DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));

+    }

+  } else {

+    DEBUG ((EFI_D_ERROR, "Attempt to write to ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));

+    ASSERT (0);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.S
new file mode 100644
index 0000000..ec4ede5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.S
@@ -0,0 +1,119 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+

+GCC_ASM_EXPORT (ArmReadCntFrq)

+GCC_ASM_EXPORT (ArmWriteCntFrq)

+GCC_ASM_EXPORT (ArmReadCntPct)

+GCC_ASM_EXPORT (ArmReadCntkCtl)

+GCC_ASM_EXPORT (ArmWriteCntkCtl)

+GCC_ASM_EXPORT (ArmReadCntpTval)

+GCC_ASM_EXPORT (ArmWriteCntpTval)

+GCC_ASM_EXPORT (ArmReadCntpCtl)

+GCC_ASM_EXPORT (ArmWriteCntpCtl)

+GCC_ASM_EXPORT (ArmReadCntvTval)

+GCC_ASM_EXPORT (ArmWriteCntvTval)

+GCC_ASM_EXPORT (ArmReadCntvCtl)

+GCC_ASM_EXPORT (ArmWriteCntvCtl)

+GCC_ASM_EXPORT (ArmReadCntvCt)

+GCC_ASM_EXPORT (ArmReadCntpCval)

+GCC_ASM_EXPORT (ArmWriteCntpCval)

+GCC_ASM_EXPORT (ArmReadCntvCval)

+GCC_ASM_EXPORT (ArmWriteCntvCval)

+GCC_ASM_EXPORT (ArmReadCntvOff)

+GCC_ASM_EXPORT (ArmWriteCntvOff)

+

+ASM_PFX(ArmReadCntFrq):

+  mrc    p15, 0, r0, c14, c0, 0    @ Read CNTFRQ

+  bx     lr

+

+ASM_PFX(ArmWriteCntFrq):

+  mcr    p15, 0, r0, c14, c0, 0    @ Write to CNTFRQ

+  bx     lr

+

+ASM_PFX(ArmReadCntPct):

+  mrrc   p15, 0, r0, r1, c14       @ Read CNTPT (Physical counter register)

+  bx     lr

+

+ASM_PFX(ArmReadCntkCtl):

+  mrc    p15, 0, r0, c14, c1, 0    @ Read CNTK_CTL (Timer PL1 Control Register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntkCtl):

+  mcr    p15, 0, r0, c14, c1, 0    @ Write to CNTK_CTL (Timer PL1 Control Register)

+  bx     lr

+

+ASM_PFX(ArmReadCntpTval):

+  mrc    p15, 0, r0, c14, c2, 0    @ Read CNTP_TVAL (PL1 physical timer value register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntpTval):

+  mcr    p15, 0, r0, c14, c2, 0    @ Write to CNTP_TVAL (PL1 physical timer value register)

+  bx     lr

+

+ASM_PFX(ArmReadCntpCtl):

+  mrc    p15, 0, r0, c14, c2, 1    @ Read CNTP_CTL (PL1 Physical Timer Control Register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntpCtl):

+  mcr    p15, 0, r0, c14, c2, 1    @ Write to  CNTP_CTL (PL1 Physical Timer Control Register)

+  bx     lr

+

+ASM_PFX(ArmReadCntvTval):

+  mrc    p15, 0, r0, c14, c3, 0    @ Read CNTV_TVAL (Virtual Timer Value register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntvTval):

+  mcr    p15, 0, r0, c14, c3, 0    @ Write to CNTV_TVAL (Virtual Timer Value register)

+  bx     lr

+

+ASM_PFX(ArmReadCntvCtl):

+  mrc    p15, 0, r0, c14, c3, 1    @ Read CNTV_CTL (Virtual Timer Control Register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntvCtl):

+  mcr    p15, 0, r0, c14, c3, 1    @ Write to CNTV_CTL (Virtual Timer Control Register)

+  bx     lr

+

+ASM_PFX(ArmReadCntvCt):

+  mrrc   p15, 1, r0, r1, c14       @ Read CNTVCT  (Virtual Count Register)

+  bx     lr

+

+ASM_PFX(ArmReadCntpCval):

+  mrrc   p15, 2, r0, r1, c14       @ Read CNTP_CTVAL (Physical Timer Compare Value Register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntpCval):

+  mcrr   p15, 2, r0, r1, c14       @ Write to CNTP_CTVAL (Physical Timer Compare Value Register)

+  bx     lr

+

+ASM_PFX(ArmReadCntvCval):

+  mrrc   p15, 3, r0, r1, c14       @ Read CNTV_CTVAL (Virtual Timer Compare Value Register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntvCval):

+  mcrr   p15, 3, r0, r1, c14       @ write to  CNTV_CTVAL (Virtual Timer Compare Value Register)

+  bx     lr

+

+ASM_PFX(ArmReadCntvOff):

+  mrrc   p15, 4, r0, r1, c14       @ Read CNTVOFF (virtual Offset register)

+  bx     lr

+

+ASM_PFX(ArmWriteCntvOff):

+  mcrr   p15, 4, r0, r1, c14       @ Write to CNTVOFF (Virtual Offset register)

+  bx     lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.asm
new file mode 100644
index 0000000..514830d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.asm
@@ -0,0 +1,119 @@
+//------------------------------------------------------------------------------

+//

+// 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.

+//

+//------------------------------------------------------------------------------

+

+    EXPORT  ArmReadCntFrq

+    EXPORT  ArmWriteCntFrq

+    EXPORT  ArmReadCntPct

+    EXPORT  ArmReadCntkCtl

+    EXPORT  ArmWriteCntkCtl

+    EXPORT  ArmReadCntpTval

+    EXPORT  ArmWriteCntpTval

+    EXPORT  ArmReadCntpCtl

+    EXPORT  ArmWriteCntpCtl

+    EXPORT  ArmReadCntvTval

+    EXPORT  ArmWriteCntvTval

+    EXPORT  ArmReadCntvCtl

+    EXPORT  ArmWriteCntvCtl

+    EXPORT  ArmReadCntvCt

+    EXPORT  ArmReadCntpCval

+    EXPORT  ArmWriteCntpCval

+    EXPORT  ArmReadCntvCval

+    EXPORT  ArmWriteCntvCval

+    EXPORT  ArmReadCntvOff

+    EXPORT  ArmWriteCntvOff

+

+    AREA    ArmV7ArchTimerSupport, CODE, READONLY

+    PRESERVE8

+

+ArmReadCntFrq

+  mrc    p15, 0, r0, c14, c0, 0    ; Read CNTFRQ

+  bx     lr

+

+ArmWriteCntFrq

+  mcr    p15, 0, r0, c14, c0, 0    ; Write to CNTFRQ

+  bx     lr

+

+ArmReadCntPct

+  mrrc   p15, 0, r0, r1, c14       ; Read CNTPT (Physical counter register)

+  bx     lr

+

+ArmReadCntkCtl

+  mrc    p15, 0, r0, c14, c1, 0    ; Read CNTK_CTL (Timer PL1 Control Register)

+  bx     lr

+

+ArmWriteCntkCtl

+  mcr    p15, 0, r0, c14, c1, 0    ; Write to CNTK_CTL (Timer PL1 Control Register)

+  bx     lr

+

+ArmReadCntpTval

+  mrc    p15, 0, r0, c14, c2, 0    ; Read CNTP_TVAL (PL1 physical timer value register)

+  bx     lr

+

+ArmWriteCntpTval

+  mcr    p15, 0, r0, c14, c2, 0    ; Write to CNTP_TVAL (PL1 physical timer value register)

+  bx     lr

+

+ArmReadCntpCtl

+  mrc    p15, 0, r0, c14, c2, 1    ; Read CNTP_CTL (PL1 Physical Timer Control Register)

+  bx     lr

+

+ArmWriteCntpCtl

+  mcr    p15, 0, r0, c14, c2, 1    ; Write to  CNTP_CTL (PL1 Physical Timer Control Register)

+  bx     lr

+

+ArmReadCntvTval

+  mrc    p15, 0, r0, c14, c3, 0    ; Read CNTV_TVAL (Virtual Timer Value register)

+  bx     lr

+

+ArmWriteCntvTval

+  mcr    p15, 0, r0, c14, c3, 0    ; Write to CNTV_TVAL (Virtual Timer Value register)

+  bx     lr

+

+ArmReadCntvCtl

+  mrc    p15, 0, r0, c14, c3, 1    ; Read CNTV_CTL (Virtual Timer Control Register)

+  bx     lr

+

+ArmWriteCntvCtl

+  mcr    p15, 0, r0, c14, c3, 1    ; Write to CNTV_CTL (Virtual Timer Control Register)

+  bx     lr

+

+ArmReadCntvCt

+  mrrc   p15, 1, r0, r1, c14       ; Read CNTVCT  (Virtual Count Register)

+  bx     lr

+

+ArmReadCntpCval

+  mrrc   p15, 2, r0, r1, c14       ; Read CNTP_CTVAL (Physical Timer Compare Value Register)

+  bx     lr

+

+ArmWriteCntpCval

+  mcrr   p15, 2, r0, r1, c14       ; Write to CNTP_CTVAL (Physical Timer Compare Value Register)

+  bx     lr

+

+ArmReadCntvCval

+  mrrc   p15, 3, r0, r1, c14       ; Read CNTV_CTVAL (Virtual Timer Compare Value Register)

+  bx     lr

+

+ArmWriteCntvCval

+  mcrr   p15, 3, r0, r1, c14       ; write to  CNTV_CTVAL (Virtual Timer Compare Value Register)

+  bx     lr

+

+ArmReadCntvOff

+  mrrc   p15, 4, r0, r1, c14       ; Read CNTVOFF (virtual Offset register)

+  bx     lr

+

+ArmWriteCntvOff

+  mcrr   p15, 4, r0, r1, c14       ; Write to CNTVOFF (Virtual Offset register)

+  bx     lr

+

+ END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c
new file mode 100644
index 0000000..feb6088
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c
@@ -0,0 +1,269 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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.

+

+**/

+#include <Uefi.h>

+#include <Chipset/ArmV7.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/IoLib.h>

+#include "ArmV7Lib.h"

+#include "ArmLibPrivate.h"

+

+ARM_CACHE_TYPE

+EFIAPI

+ArmCacheType (

+  VOID

+  )

+{

+  return ARM_CACHE_TYPE_WRITE_BACK;

+}

+

+ARM_CACHE_ARCHITECTURE

+EFIAPI

+ArmCacheArchitecture (

+  VOID

+  )

+{

+  UINT32 CLIDR = ReadCLIDR ();

+

+  return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me

+}

+

+BOOLEAN

+EFIAPI

+ArmDataCachePresent (

+  VOID

+  )

+{

+  UINT32 CLIDR = ReadCLIDR ();

+

+  if ((CLIDR & 0x2) == 0x2) {

+    // Instruction cache exists

+    return TRUE;

+  }

+  if ((CLIDR & 0x7) == 0x4) {

+    // Unified cache

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheSize (

+  VOID

+  )

+{

+  UINT32 NumSets;

+  UINT32 Associativity;

+  UINT32 LineSize;

+  UINT32 CCSIDR = ReadCCSIDR (0);

+

+  LineSize      = (1 << ((CCSIDR & 0x7) + 2));

+  Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;

+  NumSets       = ((CCSIDR >> 13) & 0x7fff) + 1;

+

+  // LineSize is in words (4 byte chunks)

+  return  NumSets * Associativity * LineSize * 4;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheAssociativity (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (0);

+

+  return ((CCSIDR >> 3) & 0x3ff) + 1;

+}

+

+UINTN

+ArmDataCacheSets (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (0);

+

+  return ((CCSIDR >> 13) & 0x7fff) + 1;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheLineLength (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (0) & 7;

+

+  // * 4 converts to bytes

+  return (1 << (CCSIDR + 2)) * 4;

+}

+

+BOOLEAN

+EFIAPI

+ArmInstructionCachePresent (

+  VOID

+  )

+{

+  UINT32 CLIDR = ReadCLIDR ();

+

+  if ((CLIDR & 1) == 1) {

+    // Instruction cache exists

+    return TRUE;

+  }

+  if ((CLIDR & 0x7) == 0x4) {

+    // Unified cache

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheSize (

+  VOID

+  )

+{

+  UINT32 NumSets;

+  UINT32 Associativity;

+  UINT32 LineSize;

+  UINT32 CCSIDR = ReadCCSIDR (1);

+

+  LineSize      = (1 << ((CCSIDR & 0x7) + 2));

+  Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;

+  NumSets       = ((CCSIDR >> 13) & 0x7fff) + 1;

+

+  // LineSize is in words (4 byte chunks)

+  return  NumSets * Associativity * LineSize * 4;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheAssociativity (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (1);

+

+  return ((CCSIDR >> 3) & 0x3ff) + 1;

+//  return 4;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheSets (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (1);

+

+  return ((CCSIDR >> 13) & 0x7fff) + 1;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheLineLength (

+  VOID

+  )

+{

+  UINT32 CCSIDR = ReadCCSIDR (1) & 7;

+

+  // * 4 converts to bytes

+  return (1 << (CCSIDR + 2)) * 4;

+

+//  return 64;

+}

+

+

+VOID

+ArmV7DataCacheOperation (

+  IN  ARM_V7_CACHE_OPERATION  DataCacheOperation

+  )

+{

+  UINTN     SavedInterruptState;

+

+  SavedInterruptState = ArmGetInterruptState ();

+  ArmDisableInterrupts ();

+

+  ArmV7AllDataCachesOperation (DataCacheOperation);

+

+  ArmDrainWriteBuffer ();

+

+  if (SavedInterruptState) {

+    ArmEnableInterrupts ();

+  }

+}

+

+

+VOID

+ArmV7PoUDataCacheOperation (

+  IN  ARM_V7_CACHE_OPERATION  DataCacheOperation

+  )

+{

+  UINTN     SavedInterruptState;

+

+  SavedInterruptState = ArmGetInterruptState ();

+  ArmDisableInterrupts ();

+

+  ArmV7PerformPoUDataCacheOperation (DataCacheOperation);

+

+  ArmDrainWriteBuffer ();

+

+  if (SavedInterruptState) {

+    ArmEnableInterrupts ();

+  }

+}

+

+VOID

+EFIAPI

+ArmInvalidateDataCache (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);

+}

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCache (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);

+}

+

+VOID

+EFIAPI

+ArmCleanDataCache (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);

+}

+

+VOID

+EFIAPI

+ArmCleanDataCacheToPoU (

+  VOID

+  )

+{

+  ArmDrainWriteBuffer ();

+  ArmV7PoUDataCacheOperation (ArmCleanDataCacheEntryBySetWay);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
new file mode 100644
index 0000000..1398d75
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
@@ -0,0 +1,32 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __ARM_V7_LIB_H__

+#define __ARM_V7_LIB_H__

+

+typedef VOID (*ARM_V7_CACHE_OPERATION)(UINT32);

+

+

+VOID

+ArmV7PerformPoUDataCacheOperation (

+  IN  ARM_V7_CACHE_OPERATION  DataCacheOperation

+  );

+

+VOID

+ArmV7AllDataCachesOperation (

+  IN  ARM_V7_CACHE_OPERATION  DataCacheOperation

+  );

+

+#endif // __ARM_V7_LIB_H__

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
new file mode 100644
index 0000000..55c0ec6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
@@ -0,0 +1,53 @@
+#/** @file

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmV7Lib

+  FILE_GUID                      = 411cdfd8-f964-4b9d-a3e3-1719a9c15559

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ArmLibSupportV7.S    | GCC

+  ArmLibSupportV7.asm  | RVCT

+

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  ArmV7Support.S    | GCC

+  ArmV7Support.asm  | RVCT

+

+  ArmV7Lib.c

+  ArmV7Mmu.c

+

+  ArmV7ArchTimer.c

+  ArmV7ArchTimerSupport.S    | GCC

+  ArmV7ArchTimerSupport.asm    | RVCT

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  MemoryAllocationLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
new file mode 100644
index 0000000..bc403d5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
@@ -0,0 +1,53 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmV7LibPrePi

+  FILE_GUID                      = A150FA0C-F4E8-4207-9BEB-CD6DFB430D73

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ArmLibSupportV7.S    | GCC

+  ArmLibSupportV7.asm  | RVCT

+

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  ArmV7Support.S    | GCC

+  ArmV7Support.asm  | RVCT

+

+  ArmV7Lib.c

+  ArmV7Mmu.c

+

+  ArmV7ArchTimer.c

+  ArmV7ArchTimerSupport.S    | GCC

+  ArmV7ArchTimerSupport.asm  | RVCT

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PrePiLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
new file mode 100644
index 0000000..4081d1a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
@@ -0,0 +1,47 @@
+#/* @file

+#  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.

+#

+#*/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmV7Lib

+  FILE_GUID                      = 411cdfd8-f964-4b9d-a3e3-1719a9c15559

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ArmLibSupportV7.S    | GCC

+  ArmLibSupportV7.asm  | RVCT

+

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+  ../Common/ArmLib.c

+

+  ArmV7Support.S    | GCC

+  ArmV7Support.asm  | RVCT

+

+  ArmV7Lib.c

+

+  ArmV7ArchTimer.c

+  ArmV7ArchTimerSupport.S    | GCC

+  ArmV7ArchTimerSupport.asm    | RVCT

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
new file mode 100644
index 0000000..d035ff3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
@@ -0,0 +1,303 @@
+/** @file

+*  File managing the MMU for ARMv7 architecture

+*

+*  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 <Uefi.h>

+#include <Chipset/ArmV7.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include "ArmV7Lib.h"

+#include "ArmLibPrivate.h"

+

+UINT32

+ConvertSectionAttributesToPageAttributes (

+  IN UINT32   SectionAttributes,

+  IN BOOLEAN  IsLargePage

+  )

+{

+  UINT32 PageAttributes;

+

+  PageAttributes = 0;

+  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);

+  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);

+  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);

+  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);

+  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);

+

+  return PageAttributes;

+}

+

+STATIC

+VOID

+PopulateLevel2PageTable (

+  IN UINT32                         *SectionEntry,

+  IN UINT32                         PhysicalBase,

+  IN UINT32                         RemainLength,

+  IN ARM_MEMORY_REGION_ATTRIBUTES   Attributes

+  )

+{

+  UINT32* PageEntry;

+  UINT32  Pages;

+  UINT32  Index;

+  UINT32  PageAttributes;

+  UINT32  SectionDescriptor;

+  UINT32  TranslationTable;

+  UINT32  BaseSectionAddress;

+

+  switch (Attributes) {

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:

+      PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:

+      PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH;

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:

+      PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE;

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:

+      PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;

+      break;

+    default:

+      PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;

+      break;

+  }

+

+  // Check if the Section Entry has already been populated. Otherwise attach a

+  // Level 2 Translation Table to it

+  if (*SectionEntry != 0) {

+    // The entry must be a page table. Otherwise it exists an overlapping in the memory map

+    if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(*SectionEntry)) {

+      TranslationTable = *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK;

+    } else if ((*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {

+      // Case where a virtual memory map descriptor overlapped a section entry

+

+      // Allocate a Level2 Page Table for this Section

+      TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));

+      TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;

+

+      // Translate the Section Descriptor into Page Descriptor

+      SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);

+

+      BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);

+

+      // Populate the new Level2 Page Table for the section

+      PageEntry = (UINT32*)TranslationTable;

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

+        PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseSectionAddress + (Index << 12)) | SectionDescriptor;

+      }

+

+      // Overwrite the section entry to point to the new Level2 Translation Table

+      *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |

+          (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |

+          TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;

+    } else {

+      // We do not support the other section type (16MB Section)

+      ASSERT(0);

+      return;

+    }

+  } else {

+    TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));

+    TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;

+

+    ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);

+

+    *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |

+        (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |

+        TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;

+  }

+

+  PageEntry = ((UINT32 *)(TranslationTable) + ((PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT));

+  Pages     = RemainLength / TT_DESCRIPTOR_PAGE_SIZE;

+

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

+    *PageEntry++     =  TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes;

+    PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;

+  }

+

+}

+

+STATIC

+VOID

+FillTranslationTable (

+  IN  UINT32                        *TranslationTable,

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion

+  )

+{

+  UINT32  *SectionEntry;

+  UINT32  Attributes;

+  UINT32  PhysicalBase = MemoryRegion->PhysicalBase;

+  UINT32  RemainLength = MemoryRegion->Length;

+

+  ASSERT(MemoryRegion->Length > 0);

+

+  switch (MemoryRegion->Attributes) {

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:

+      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:

+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:

+      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);

+      break;

+    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);

+      break;

+    default:

+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);

+      break;

+  }

+

+  // Get the first section entry for this mapping

+  SectionEntry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);

+

+  while (RemainLength != 0) {

+    if (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0) {

+      if (RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {

+        // Case: Physical address aligned on the Section Size (1MB) && the length is greater than the Section Size

+        *SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;

+        PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;

+      } else {

+        // Case: Physical address aligned on the Section Size (1MB) && the length does not fill a section

+        PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);

+

+        // It must be the last entry

+        break;

+      }

+    } else {

+      // Case: Physical address NOT aligned on the Section Size (1MB)

+      PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);

+      // Aligned the address

+      PhysicalBase = (PhysicalBase + TT_DESCRIPTOR_SECTION_SIZE) & ~(TT_DESCRIPTOR_SECTION_SIZE-1);

+

+      // If it is the last entry

+      if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {

+        break;

+      }

+    }

+    RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;

+  }

+}

+

+RETURN_STATUS

+EFIAPI

+ArmConfigureMmu (

+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,

+  OUT VOID                         **TranslationTableBase OPTIONAL,

+  OUT UINTN                         *TranslationTableSize OPTIONAL

+  )

+{

+  VOID*                         TranslationTable;

+  ARM_MEMORY_REGION_ATTRIBUTES  TranslationTableAttribute;

+  UINT32                        TTBRAttributes;

+

+  // Allocate pages for translation table.

+  TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));

+  if (TranslationTable == NULL) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);

+

+  if (TranslationTableBase != NULL) {

+    *TranslationTableBase = TranslationTable;

+  }

+

+  if (TranslationTableSize != NULL) {

+    *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;

+  }

+

+  ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);

+

+  // By default, mark the translation table as belonging to a uncached region

+  TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;

+  while (MemoryTable->Length != 0) {

+    // Find the memory attribute for the Translation Table

+    if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {

+      TranslationTableAttribute = MemoryTable->Attributes;

+    }

+

+    FillTranslationTable (TranslationTable, MemoryTable);

+    MemoryTable++;

+  }

+

+  // Translate the Memory Attributes into Translation Table Register Attributes

+  if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||

+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {

+    TTBRAttributes = TTBR_NON_CACHEABLE;

+  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||

+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {

+    TTBRAttributes = TTBR_WRITE_BACK_ALLOC;

+  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||

+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {

+    TTBRAttributes = TTBR_WRITE_THROUGH_NO_ALLOC;

+  } else {

+    ASSERT (0); // No support has been found for the attributes of the memory region that the translation table belongs to.

+    return RETURN_UNSUPPORTED;

+  }

+

+  ArmCleanInvalidateDataCache ();

+  ArmInvalidateInstructionCache ();

+

+  ArmDisableDataCache ();

+  ArmDisableInstructionCache();

+  // TLBs are also invalidated when calling ArmDisableMmu()

+  ArmDisableMmu ();

+

+  // Make sure nothing sneaked into the cache

+  ArmCleanInvalidateDataCache ();

+  ArmInvalidateInstructionCache ();

+

+  ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));

+

+  ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |

+                             DOMAIN_ACCESS_CONTROL_NONE(14) |

+                             DOMAIN_ACCESS_CONTROL_NONE(13) |

+                             DOMAIN_ACCESS_CONTROL_NONE(12) |

+                             DOMAIN_ACCESS_CONTROL_NONE(11) |

+                             DOMAIN_ACCESS_CONTROL_NONE(10) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 9) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 8) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 7) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 6) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 5) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 4) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 3) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 2) |

+                             DOMAIN_ACCESS_CONTROL_NONE( 1) |

+                             DOMAIN_ACCESS_CONTROL_MANAGER(0));

+

+  ArmEnableInstructionCache();

+  ArmEnableDataCache();

+  ArmEnableMmu();

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
new file mode 100644
index 0000000..af5ec23
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
@@ -0,0 +1,391 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+

+GCC_ASM_EXPORT (ArmInvalidateInstructionCache)

+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)

+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)

+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)

+GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)

+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryBySetWay)

+GCC_ASM_EXPORT (ArmDrainWriteBuffer)

+GCC_ASM_EXPORT (ArmEnableMmu)

+GCC_ASM_EXPORT (ArmDisableMmu)

+GCC_ASM_EXPORT (ArmDisableCachesAndMmu)

+GCC_ASM_EXPORT (ArmMmuEnabled)

+GCC_ASM_EXPORT (ArmEnableDataCache)

+GCC_ASM_EXPORT (ArmDisableDataCache)

+GCC_ASM_EXPORT (ArmEnableInstructionCache)

+GCC_ASM_EXPORT (ArmDisableInstructionCache)

+GCC_ASM_EXPORT (ArmEnableSWPInstruction)

+GCC_ASM_EXPORT (ArmEnableBranchPrediction)

+GCC_ASM_EXPORT (ArmDisableBranchPrediction)

+GCC_ASM_EXPORT (ArmSetLowVectors)

+GCC_ASM_EXPORT (ArmSetHighVectors)

+GCC_ASM_EXPORT (ArmV7AllDataCachesOperation)

+GCC_ASM_EXPORT (ArmV7PerformPoUDataCacheOperation)

+GCC_ASM_EXPORT (ArmDataMemoryBarrier)

+GCC_ASM_EXPORT (ArmDataSyncronizationBarrier)

+GCC_ASM_EXPORT (ArmInstructionSynchronizationBarrier)

+GCC_ASM_EXPORT (ArmReadVBar)

+GCC_ASM_EXPORT (ArmWriteVBar)

+GCC_ASM_EXPORT (ArmEnableVFP)

+GCC_ASM_EXPORT (ArmCallWFI)

+GCC_ASM_EXPORT (ArmReadCbar)

+GCC_ASM_EXPORT (ArmReadMpidr)

+GCC_ASM_EXPORT (ArmReadTpidrurw)

+GCC_ASM_EXPORT (ArmWriteTpidrurw)

+GCC_ASM_EXPORT (ArmIsArchTimerImplemented)

+GCC_ASM_EXPORT (ArmReadIdPfr1)

+

+.set DC_ON, (0x1<<2)

+.set IC_ON, (0x1<<12)

+.set CTRL_M_BIT,  (1 << 0)

+.set CTRL_C_BIT,  (1 << 2)

+.set CTRL_B_BIT,  (1 << 7)

+.set CTRL_I_BIT,  (1 << 12)

+

+

+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c6, 1   @invalidate single data cache line

+  dsb

+  isb

+  bx      lr

+

+ASM_PFX(ArmCleanDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c10, 1  @clean single data cache line

+  dsb

+  isb

+  bx      lr

+

+

+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):

+  mcr     p15, 0, r0, c7, c14, 1  @clean and invalidate single data cache line

+  dsb

+  isb

+  bx      lr

+

+

+ASM_PFX(ArmInvalidateDataCacheEntryBySetWay):

+  mcr     p15, 0, r0, c7, c6, 2        @ Invalidate this line

+  dsb

+  isb

+  bx      lr

+

+

+ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay):

+  mcr     p15, 0, r0, c7, c14, 2       @ Clean and Invalidate this line

+  dsb

+  isb

+  bx      lr

+

+

+ASM_PFX(ArmCleanDataCacheEntryBySetWay):

+  mcr     p15, 0, r0, c7, c10, 2       @ Clean this line

+  dsb

+  isb

+  bx      lr

+

+ASM_PFX(ArmInvalidateInstructionCache):

+  mcr     p15,0,R0,c7,c5,0      @Invalidate entire instruction cache

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableMmu):

+  mrc     p15,0,R0,c1,c0,0

+  orr     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0

+  dsb

+  isb

+  bx      LR

+

+

+ASM_PFX(ArmDisableMmu):

+  mrc     p15,0,R0,c1,c0,0

+  bic     R0,R0,#1

+  mcr     p15,0,R0,c1,c0,0      @Disable MMU

+

+  mcr     p15,0,R0,c8,c7,0      @Invalidate TLB

+  mcr     p15,0,R0,c7,c5,6      @Invalidate Branch predictor array

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableCachesAndMmu):

+  mrc   p15, 0, r0, c1, c0, 0           @ Get control register

+  bic   r0, r0, #CTRL_M_BIT             @ Disable MMU

+  bic   r0, r0, #CTRL_C_BIT             @ Disable D Cache

+  bic   r0, r0, #CTRL_I_BIT             @ Disable I Cache

+  mcr   p15, 0, r0, c1, c0, 0           @ Write control register

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmMmuEnabled):

+  mrc     p15,0,R0,c1,c0,0

+  and     R0,R0,#1

+  bx      LR

+

+ASM_PFX(ArmEnableDataCache):

+  ldr     R1,=DC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  orr     R0,R0,R1              @Set C bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableDataCache):

+  ldr     R1,=DC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  bic     R0,R0,R1              @Clear C bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableInstructionCache):

+  ldr     R1,=IC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  orr     R0,R0,R1              @Set I bit

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableInstructionCache):

+  ldr     R1,=IC_ON

+  mrc     p15,0,R0,c1,c0,0      @Read control register configuration data

+  bic     R0,R0,R1              @Clear I bit.

+  mcr     p15,0,r0,c1,c0,0      @Write control register configuration data

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableSWPInstruction):

+  mrc     p15, 0, r0, c1, c0, 0

+  orr     r0, r0, #0x00000400

+  mcr     p15, 0, r0, c1, c0, 0

+  isb

+  bx      LR

+

+ASM_PFX(ArmEnableBranchPrediction):

+  mrc     p15, 0, r0, c1, c0, 0

+  orr     r0, r0, #0x00000800

+  mcr     p15, 0, r0, c1, c0, 0

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmDisableBranchPrediction):

+  mrc     p15, 0, r0, c1, c0, 0

+  bic     r0, r0, #0x00000800

+  mcr     p15, 0, r0, c1, c0, 0

+  dsb

+  isb

+  bx      LR

+

+ASM_PFX(ArmSetLowVectors):

+  mrc     p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)

+  bic     r0, r0, #0x00002000   @ clear V bit

+  mcr     p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      LR

+

+ASM_PFX(ArmSetHighVectors):

+  mrc     p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)

+  orr     r0, r0, #0x00002000   @ Set V bit

+  mcr     p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      LR

+

+ASM_PFX(ArmV7AllDataCachesOperation):

+  stmfd SP!,{r4-r12, LR}

+  mov   R1, R0                @ Save Function call in R1

+  mrc   p15, 1, R6, c0, c0, 1 @ Read CLIDR

+  ands  R3, R6, #0x7000000    @ Mask out all but Level of Coherency (LoC)

+  mov   R3, R3, LSR #23       @ Cache level value (naturally aligned)

+  beq   L_Finished

+  mov   R10, #0

+

+Loop1:

+  add   R2, R10, R10, LSR #1  @ Work out 3xcachelevel

+  mov   R12, R6, LSR R2       @ bottom 3 bits are the Cache type for this level

+  and   R12, R12, #7          @ get those 3 bits alone

+  cmp   R12, #2

+  blt   L_Skip                  @ no cache or only instruction cache at this level

+  mcr   p15, 2, R10, c0, c0, 0  @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction

+  isb                           @ isb to sync the change to the CacheSizeID reg

+  mrc   p15, 1, R12, c0, c0, 0  @ reads current Cache Size ID register (CCSIDR)

+  and   R2, R12, #0x7           @ extract the line length field

+  add   R2, R2, #4              @ add 4 for the line length offset (log2 16 bytes)

+@  ldr   R4, =0x3FF

+  mov   R4, #0x400

+  sub   R4, R4, #1

+  ands  R4, R4, R12, LSR #3     @ R4 is the max number on the way size (right aligned)

+  clz   R5, R4                  @ R5 is the bit position of the way size increment

+@  ldr   R7, =0x00007FFF

+  mov   R7, #0x00008000

+  sub   R7, R7, #1

+  ands  R7, R7, R12, LSR #13    @ R7 is the max number of the index size (right aligned)

+

+Loop2:

+  mov   R9, R4                  @ R9 working copy of the max way size (right aligned)

+

+Loop3:

+  orr   R0, R10, R9, LSL R5     @ factor in the way number and cache number into R11

+  orr   R0, R0, R7, LSL R2      @ factor in the index number

+

+  blx   R1

+

+  subs  R9, R9, #1              @ decrement the way number

+  bge   Loop3

+  subs  R7, R7, #1              @ decrement the index

+  bge   Loop2

+L_Skip:

+  add   R10, R10, #2            @ increment the cache number

+  cmp   R3, R10

+  bgt   Loop1

+

+L_Finished:

+  dsb

+  ldmfd SP!, {r4-r12, lr}

+  bx    LR

+

+ASM_PFX(ArmV7PerformPoUDataCacheOperation):

+  stmfd SP!,{r4-r12, LR}

+  mov   R1, R0                @ Save Function call in R1

+  mrc   p15, 1, R6, c0, c0, 1 @ Read CLIDR

+  ands  R3, R6, #0x38000000    @ Mask out all but Level of Unification (LoU)

+  mov   R3, R3, LSR #26       @ Cache level value (naturally aligned)

+  beq   Finished2

+  mov   R10, #0

+

+Loop4:

+  add   R2, R10, R10, LSR #1    @ Work out 3xcachelevel

+  mov   R12, R6, LSR R2         @ bottom 3 bits are the Cache type for this level

+  and   R12, R12, #7            @ get those 3 bits alone

+  cmp   R12, #2

+  blt   Skip2                   @ no cache or only instruction cache at this level

+  mcr   p15, 2, R10, c0, c0, 0  @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction

+  isb                           @ isb to sync the change to the CacheSizeID reg

+  mrc   p15, 1, R12, c0, c0, 0  @ reads current Cache Size ID register (CCSIDR)

+  and   R2, R12, #0x7            @ extract the line length field

+  add   R2, R2, #4              @ add 4 for the line length offset (log2 16 bytes)

+  ldr   R4, =0x3FF

+  ands  R4, R4, R12, LSR #3     @ R4 is the max number on the way size (right aligned)

+  clz   R5, R4                  @ R5 is the bit position of the way size increment

+  ldr   R7, =0x00007FFF

+  ands  R7, R7, R12, LSR #13    @ R7 is the max number of the index size (right aligned)

+

+Loop5:

+  mov   R9, R4                  @ R9 working copy of the max way size (right aligned)

+

+Loop6:

+  orr   R0, R10, R9, LSL R5     @ factor in the way number and cache number into R11

+  orr   R0, R0, R7, LSL R2      @ factor in the index number

+

+  blx   R1

+

+  subs  R9, R9, #1              @ decrement the way number

+  bge   Loop6

+  subs  R7, R7, #1              @ decrement the index

+  bge   Loop5

+Skip2:

+  add   R10, R10, #2            @ increment the cache number

+  cmp   R3, R10

+  bgt   Loop4

+

+Finished2:

+  dsb

+  ldmfd SP!, {r4-r12, lr}

+  bx    LR

+

+ASM_PFX(ArmDataMemoryBarrier):

+  dmb

+  bx      LR

+

+ASM_PFX(ArmDataSyncronizationBarrier):

+ASM_PFX(ArmDrainWriteBuffer):

+  dsb

+  bx      LR

+

+ASM_PFX(ArmInstructionSynchronizationBarrier):

+  isb

+  bx      LR

+

+ASM_PFX(ArmReadVBar):

+  # Set the Address of the Vector Table in the VBAR register

+  mrc     p15, 0, r0, c12, c0, 0

+  bx      lr

+

+ASM_PFX(ArmWriteVBar):

+  # Set the Address of the Vector Table in the VBAR register

+  mcr     p15, 0, r0, c12, c0, 0

+  # Ensure the SCTLR.V bit is clear

+  mrc     p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)

+  bic     r0, r0, #0x00002000   @ clear V bit

+  mcr     p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      lr

+

+ASM_PFX(ArmEnableVFP):

+  # Read CPACR (Coprocessor Access Control Register)

+  mrc     p15, 0, r0, c1, c0, 2

+  # Enable VPF access (Full Access to CP10, CP11) (V* instructions)

+  orr     r0, r0, #0x00f00000

+  # Write back CPACR (Coprocessor Access Control Register)

+  mcr     p15, 0, r0, c1, c0, 2

+  isb

+  # Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.

+  mov     r0, #0x40000000

+  mcr     p10,#0x7,r0,c8,c0,#0

+  bx      lr

+

+ASM_PFX(ArmCallWFI):

+  wfi

+  bx      lr

+

+#Note: Return 0 in Uniprocessor implementation

+ASM_PFX(ArmReadCbar):

+  mrc     p15, 4, r0, c15, c0, 0  @ Read Configuration Base Address Register

+  bx      lr

+

+ASM_PFX(ArmReadMpidr):

+  mrc     p15, 0, r0, c0, c0, 5       @ read MPIDR

+  bx      lr

+

+ASM_PFX(ArmReadTpidrurw):

+  mrc     p15, 0, r0, c13, c0, 2    @ read TPIDRURW

+  bx      lr

+

+ASM_PFX(ArmWriteTpidrurw):

+  mcr     p15, 0, r0, c13, c0, 2    @ write TPIDRURW

+  bx      lr

+

+ASM_PFX(ArmIsArchTimerImplemented):

+  mrc    p15, 0, r0, c0, c1, 1     @ Read ID_PFR1

+  and    r0, r0, #0x000F0000

+  bx     lr

+

+ASM_PFX(ArmReadIdPfr1):

+  mrc    p15, 0, r0, c0, c1, 1     @ Read ID_PFR1 Register

+  bx     lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
new file mode 100644
index 0000000..2b13811
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
@@ -0,0 +1,385 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+// 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.

+//

+//------------------------------------------------------------------------------

+

+    EXPORT  ArmInvalidateInstructionCache

+    EXPORT  ArmInvalidateDataCacheEntryByMVA

+    EXPORT  ArmCleanDataCacheEntryByMVA

+    EXPORT  ArmCleanInvalidateDataCacheEntryByMVA

+    EXPORT  ArmInvalidateDataCacheEntryBySetWay

+    EXPORT  ArmCleanDataCacheEntryBySetWay

+    EXPORT  ArmCleanInvalidateDataCacheEntryBySetWay

+    EXPORT  ArmDrainWriteBuffer

+    EXPORT  ArmEnableMmu

+    EXPORT  ArmDisableMmu

+    EXPORT  ArmDisableCachesAndMmu

+    EXPORT  ArmMmuEnabled

+    EXPORT  ArmEnableDataCache

+    EXPORT  ArmDisableDataCache

+    EXPORT  ArmEnableInstructionCache

+    EXPORT  ArmDisableInstructionCache

+    EXPORT  ArmEnableSWPInstruction

+    EXPORT  ArmEnableBranchPrediction

+    EXPORT  ArmDisableBranchPrediction

+    EXPORT  ArmSetLowVectors

+    EXPORT  ArmSetHighVectors

+    EXPORT  ArmV7AllDataCachesOperation

+    EXPORT  ArmV7PerformPoUDataCacheOperation

+    EXPORT  ArmDataMemoryBarrier

+    EXPORT  ArmDataSyncronizationBarrier

+    EXPORT  ArmInstructionSynchronizationBarrier

+    EXPORT  ArmReadVBar

+    EXPORT  ArmWriteVBar

+    EXPORT  ArmEnableVFP

+    EXPORT  ArmCallWFI

+    EXPORT  ArmReadCbar

+    EXPORT  ArmReadMpidr

+    EXPORT  ArmReadTpidrurw

+    EXPORT  ArmWriteTpidrurw

+    EXPORT  ArmIsArchTimerImplemented

+    EXPORT  ArmReadIdPfr1

+

+    AREA    ArmV7Support, CODE, READONLY

+    PRESERVE8

+

+DC_ON           EQU     ( 0x1:SHL:2 )

+IC_ON           EQU     ( 0x1:SHL:12 )

+CTRL_M_BIT      EQU     (1 << 0)

+CTRL_C_BIT      EQU     (1 << 2)

+CTRL_B_BIT      EQU     (1 << 7)

+CTRL_I_BIT      EQU     (1 << 12)

+

+

+ArmInvalidateDataCacheEntryByMVA

+  mcr     p15, 0, r0, c7, c6, 1   ; invalidate single data cache line

+  dsb

+  isb

+  bx      lr

+

+ArmCleanDataCacheEntryByMVA

+  mcr     p15, 0, r0, c7, c10, 1  ; clean single data cache line

+  dsb

+  isb

+  bx      lr

+

+

+ArmCleanInvalidateDataCacheEntryByMVA

+  mcr     p15, 0, r0, c7, c14, 1  ; clean and invalidate single data cache line

+  dsb

+  isb

+  bx      lr

+

+

+ArmInvalidateDataCacheEntryBySetWay

+  mcr     p15, 0, r0, c7, c6, 2        ; Invalidate this line

+  dsb

+  isb

+  bx      lr

+

+

+ArmCleanInvalidateDataCacheEntryBySetWay

+  mcr     p15, 0, r0, c7, c14, 2       ; Clean and Invalidate this line

+  dsb

+  isb

+  bx      lr

+

+

+ArmCleanDataCacheEntryBySetWay

+  mcr     p15, 0, r0, c7, c10, 2       ; Clean this line

+  dsb

+  isb

+  bx      lr

+

+

+ArmInvalidateInstructionCache

+  mcr     p15,0,R0,c7,c5,0      ;Invalidate entire instruction cache

+  isb

+  bx      LR

+

+ArmEnableMmu

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  orr     R0,R0,#1              ; Set SCTLR.M bit : Enable MMU

+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)

+  dsb

+  isb

+  bx      LR

+

+ArmDisableMmu

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  bic     R0,R0,#1              ; Clear SCTLR.M bit : Disable MMU

+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)

+

+  mcr     p15,0,R0,c8,c7,0      ; TLBIALL : Invalidate unified TLB

+  mcr     p15,0,R0,c7,c5,6      ; BPIALL  : Invalidate entire branch predictor array

+  dsb

+  isb

+  bx      LR

+

+ArmDisableCachesAndMmu

+  mrc   p15, 0, r0, c1, c0, 0           ; Get control register

+  bic   r0, r0, #CTRL_M_BIT             ; Disable MMU

+  bic   r0, r0, #CTRL_C_BIT             ; Disable D Cache

+  bic   r0, r0, #CTRL_I_BIT             ; Disable I Cache

+  mcr   p15, 0, r0, c1, c0, 0           ; Write control register

+  dsb

+  isb

+  bx      LR

+

+ArmMmuEnabled

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  and     R0,R0,#1

+  bx      LR

+

+ArmEnableDataCache

+  ldr     R1,=DC_ON             ; Specify SCTLR.C bit : (Data) Cache enable bit

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  orr     R0,R0,R1              ; Set SCTLR.C bit : Data and unified caches enabled

+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)

+  dsb

+  isb

+  bx      LR

+

+ArmDisableDataCache

+  ldr     R1,=DC_ON             ; Specify SCTLR.C bit : (Data) Cache enable bit

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  bic     R0,R0,R1              ; Clear SCTLR.C bit : Data and unified caches disabled

+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)

+  dsb

+  isb

+  bx      LR

+

+ArmEnableInstructionCache

+  ldr     R1,=IC_ON             ; Specify SCTLR.I bit : Instruction cache enable bit

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  orr     R0,R0,R1              ; Set SCTLR.I bit : Instruction caches enabled

+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)

+  dsb

+  isb

+  bx      LR

+

+ArmDisableInstructionCache

+  ldr     R1,=IC_ON             ; Specify SCTLR.I bit : Instruction cache enable bit

+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)

+  BIC     R0,R0,R1              ; Clear SCTLR.I bit : Instruction caches disabled

+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      LR

+

+ArmEnableSWPInstruction

+  mrc     p15, 0, r0, c1, c0, 0

+  orr     r0, r0, #0x00000400

+  mcr     p15, 0, r0, c1, c0, 0

+  isb

+  bx      LR

+

+ArmEnableBranchPrediction

+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)

+  orr     r0, r0, #0x00000800   ;

+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)

+  dsb

+  isb

+  bx      LR

+

+ArmDisableBranchPrediction

+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)

+  bic     r0, r0, #0x00000800   ;

+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)

+  dsb

+  isb

+  bx      LR

+

+ArmSetLowVectors

+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)

+  bic     r0, r0, #0x00002000   ; clear V bit

+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      LR

+

+ArmSetHighVectors

+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)

+  orr     r0, r0, #0x00002000   ; Set V bit

+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      LR

+

+ArmV7AllDataCachesOperation

+  stmfd SP!,{r4-r12, LR}

+  mov   R1, R0                ; Save Function call in R1

+  mrc   p15, 1, R6, c0, c0, 1 ; Read CLIDR

+  ands  R3, R6, #&7000000     ; Mask out all but Level of Coherency (LoC)

+  mov   R3, R3, LSR #23       ; Cache level value (naturally aligned)

+  beq   Finished

+  mov   R10, #0

+

+Loop1

+  add   R2, R10, R10, LSR #1    ; Work out 3xcachelevel

+  mov   R12, R6, LSR R2         ; bottom 3 bits are the Cache type for this level

+  and   R12, R12, #7            ; get those 3 bits alone

+  cmp   R12, #2

+  blt   Skip                    ; no cache or only instruction cache at this level

+  mcr   p15, 2, R10, c0, c0, 0  ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction

+  isb                           ; isb to sync the change to the CacheSizeID reg

+  mrc   p15, 1, R12, c0, c0, 0  ; reads current Cache Size ID register (CCSIDR)

+  and   R2, R12, #&7            ; extract the line length field

+  add   R2, R2, #4              ; add 4 for the line length offset (log2 16 bytes)

+  ldr   R4, =0x3FF

+  ands  R4, R4, R12, LSR #3     ; R4 is the max number on the way size (right aligned)

+  clz   R5, R4                  ; R5 is the bit position of the way size increment

+  ldr   R7, =0x00007FFF

+  ands  R7, R7, R12, LSR #13    ; R7 is the max number of the index size (right aligned)

+

+Loop2

+  mov   R9, R4                  ; R9 working copy of the max way size (right aligned)

+

+Loop3

+  orr   R0, R10, R9, LSL R5     ; factor in the way number and cache number into R11

+  orr   R0, R0, R7, LSL R2      ; factor in the index number

+

+  blx   R1

+

+  subs  R9, R9, #1              ; decrement the way number

+  bge   Loop3

+  subs  R7, R7, #1              ; decrement the index

+  bge   Loop2

+Skip

+  add   R10, R10, #2            ; increment the cache number

+  cmp   R3, R10

+  bgt   Loop1

+

+Finished

+  dsb

+  ldmfd SP!, {r4-r12, lr}

+  bx    LR

+

+ArmV7PerformPoUDataCacheOperation

+  stmfd SP!,{r4-r12, LR}

+  mov   R1, R0                ; Save Function call in R1

+  mrc   p15, 1, R6, c0, c0, 1 ; Read CLIDR

+  ands  R3, R6, #&38000000    ; Mask out all but Level of Unification (LoU)

+  mov   R3, R3, LSR #26       ; Cache level value (naturally aligned)

+  beq   Finished2

+  mov   R10, #0

+

+Loop4

+  add   R2, R10, R10, LSR #1    ; Work out 3xcachelevel

+  mov   R12, R6, LSR R2         ; bottom 3 bits are the Cache type for this level

+  and   R12, R12, #7            ; get those 3 bits alone

+  cmp   R12, #2

+  blt   Skip2                   ; no cache or only instruction cache at this level

+  mcr   p15, 2, R10, c0, c0, 0  ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction

+  isb                           ; isb to sync the change to the CacheSizeID reg

+  mrc   p15, 1, R12, c0, c0, 0  ; reads current Cache Size ID register (CCSIDR)

+  and   R2, R12, #&7            ; extract the line length field

+  add   R2, R2, #4              ; add 4 for the line length offset (log2 16 bytes)

+  ldr   R4, =0x3FF

+  ands  R4, R4, R12, LSR #3     ; R4 is the max number on the way size (right aligned)

+  clz   R5, R4                  ; R5 is the bit position of the way size increment

+  ldr   R7, =0x00007FFF

+  ands  R7, R7, R12, LSR #13    ; R7 is the max number of the index size (right aligned)

+

+Loop5

+  mov   R9, R4                  ; R9 working copy of the max way size (right aligned)

+

+Loop6

+  orr   R0, R10, R9, LSL R5     ; factor in the way number and cache number into R11

+  orr   R0, R0, R7, LSL R2      ; factor in the index number

+

+  blx   R1

+

+  subs  R9, R9, #1              ; decrement the way number

+  bge   Loop6

+  subs  R7, R7, #1              ; decrement the index

+  bge   Loop5

+Skip2

+  add   R10, R10, #2            ; increment the cache number

+  cmp   R3, R10

+  bgt   Loop4

+

+Finished2

+  dsb

+  ldmfd SP!, {r4-r12, lr}

+  bx    LR

+

+ArmDataMemoryBarrier

+  dmb

+  bx      LR

+

+ArmDataSyncronizationBarrier

+ArmDrainWriteBuffer

+  dsb

+  bx      LR

+

+ArmInstructionSynchronizationBarrier

+  isb

+  bx      LR

+

+ArmReadVBar

+  // Set the Address of the Vector Table in the VBAR register

+  mrc     p15, 0, r0, c12, c0, 0

+  bx      lr

+

+ArmWriteVBar

+  // Set the Address of the Vector Table in the VBAR register

+  mcr     p15, 0, r0, c12, c0, 0

+  // Ensure the SCTLR.V bit is clear

+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)

+  bic     r0, r0, #0x00002000   ; clear V bit

+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)

+  isb

+  bx      lr

+

+ArmEnableVFP

+  // Read CPACR (Coprocessor Access Control Register)

+  mrc     p15, 0, r0, c1, c0, 2

+  // Enable VPF access (Full Access to CP10, CP11) (V* instructions)

+  orr     r0, r0, #0x00f00000

+  // Write back CPACR (Coprocessor Access Control Register)

+  mcr     p15, 0, r0, c1, c0, 2

+  isb

+  // Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.

+  mov     r0, #0x40000000

+  mcr     p10,#0x7,r0,c8,c0,#0

+  bx      lr

+

+ArmCallWFI

+  wfi

+  bx      lr

+

+//Note: Return 0 in Uniprocessor implementation

+ArmReadCbar

+  mrc     p15, 4, r0, c15, c0, 0  //Read Configuration Base Address Register

+  bx      lr

+

+ArmReadMpidr

+  mrc     p15, 0, r0, c0, c0, 5     ; read MPIDR

+  bx      lr

+

+ArmReadTpidrurw

+  mrc     p15, 0, r0, c13, c0, 2    ; read TPIDRURW

+  bx      lr

+

+ArmWriteTpidrurw

+  mcr     p15, 0, r0, c13, c0, 2   ; write TPIDRURW

+  bx      lr

+

+ArmIsArchTimerImplemented

+  mrc    p15, 0, r0, c0, c1, 1     ; Read ID_PFR1

+  and    r0, r0, #0x000F0000

+  bx     lr

+

+ArmReadIdPfr1

+  mrc    p15, 0, r0, c0, c1, 1     ; Read ID_PFR1 Register

+  bx     lr

+

+ END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
new file mode 100644
index 0000000..28db98b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
@@ -0,0 +1,211 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#include <AsmMacroIoLibV8.h>

+

+.text

+.align 3

+GCC_ASM_EXPORT (ArmReadMidr)

+GCC_ASM_EXPORT (ArmCacheInfo)

+GCC_ASM_EXPORT (ArmGetInterruptState)

+GCC_ASM_EXPORT (ArmGetFiqState)

+GCC_ASM_EXPORT (ArmGetTTBR0BaseAddress)

+GCC_ASM_EXPORT (ArmSetTTBR0)

+GCC_ASM_EXPORT (ArmGetTCR)

+GCC_ASM_EXPORT (ArmSetTCR)

+GCC_ASM_EXPORT (ArmGetMAIR)

+GCC_ASM_EXPORT (ArmSetMAIR)

+GCC_ASM_EXPORT (ArmWriteCpacr)

+GCC_ASM_EXPORT (ArmWriteAuxCr)

+GCC_ASM_EXPORT (ArmReadAuxCr)

+GCC_ASM_EXPORT (ArmInvalidateTlb)

+GCC_ASM_EXPORT (ArmUpdateTranslationTableEntry)

+GCC_ASM_EXPORT (ArmWriteCptr)

+GCC_ASM_EXPORT (ArmWriteScr)

+GCC_ASM_EXPORT (ArmWriteMVBar)

+GCC_ASM_EXPORT (ArmCallWFE)

+GCC_ASM_EXPORT (ArmCallSEV)

+GCC_ASM_EXPORT (ArmReadCpuActlr)

+GCC_ASM_EXPORT (ArmWriteCpuActlr)

+

+#------------------------------------------------------------------------------

+

+.set DAIF_FIQ_BIT,   (1 << 0)

+.set DAIF_IRQ_BIT,   (1 << 1)

+

+ASM_PFX(ArmReadMidr):

+  mrs     x0, midr_el1        // Read from Main ID Register (MIDR)

+  ret

+

+ASM_PFX(ArmCacheInfo):

+  mrs     x0, ctr_el0         // Read from Cache Type Regiter (CTR)

+  ret

+

+ASM_PFX(ArmGetInterruptState):

+  mrs     x0, daif

+  tst     w0, #DAIF_IRQ_BIT   // Check if IRQ is enabled. Enabled if 0.

+  mov     w0, #0

+  mov     w1, #1

+  csel    w0, w1, w0, ne

+  ret

+

+ASM_PFX(ArmGetFiqState):

+  mrs     x0, daif

+  tst     w0, #DAIF_FIQ_BIT   // Check if FIQ is enabled. Enabled if 0.

+  mov     w0, #0

+  mov     w1, #1

+  csel    w0, w1, w0, ne

+  ret

+

+ASM_PFX(ArmWriteCpacr):

+  msr     cpacr_el1, x0      // Coprocessor Access Control Reg (CPACR)

+  ret

+

+ASM_PFX(ArmWriteAuxCr):

+  EL1_OR_EL2(x1)

+1:msr     actlr_el1, x0      // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3

+  ret

+2:msr     actlr_el2, x0      // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3

+  ret

+

+ASM_PFX(ArmReadAuxCr):

+  EL1_OR_EL2(x1)

+1:mrs     x0, actlr_el1      // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3

+  ret

+2:mrs     x0, actlr_el2      // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3

+  ret

+

+ASM_PFX(ArmSetTTBR0):

+  EL1_OR_EL2_OR_EL3(x1)

+1:msr     ttbr0_el1, x0      // Translation Table Base Reg 0 (TTBR0)

+  b       4f

+2:msr     ttbr0_el2, x0      // Translation Table Base Reg 0 (TTBR0)

+  b       4f

+3:msr     ttbr0_el3, x0      // Translation Table Base Reg 0 (TTBR0)

+4:isb

+  ret

+

+ASM_PFX(ArmGetTTBR0BaseAddress):

+  EL1_OR_EL2(x1)

+1:mrs     x0, ttbr0_el1

+  b       3f

+2:mrs     x0, ttbr0_el2

+3:LoadConstantToReg(0xFFFFFFFFFFFF, x1) /* Look at bottom 48 bits */

+  and     x0, x0, x1

+  isb

+  ret

+

+ASM_PFX(ArmGetTCR):

+  EL1_OR_EL2_OR_EL3(x1)

+1:mrs     x0, tcr_el1

+  b       4f

+2:mrs     x0, tcr_el2

+  b       4f

+3:mrs     x0, tcr_el3

+4:isb

+  ret

+

+ASM_PFX(ArmSetTCR):

+  EL1_OR_EL2_OR_EL3(x1)

+1:msr     tcr_el1, x0

+  b       4f

+2:msr     tcr_el2, x0

+  b       4f

+3:msr     tcr_el3, x0

+4:isb

+  ret

+

+ASM_PFX(ArmGetMAIR):

+  EL1_OR_EL2_OR_EL3(x1)

+1:mrs     x0, mair_el1

+  b       4f

+2:mrs     x0, mair_el2

+  b       4f

+3:mrs     x0, mair_el3

+4:isb

+  ret

+

+ASM_PFX(ArmSetMAIR):

+  EL1_OR_EL2_OR_EL3(x1)

+1:msr     mair_el1, x0

+  b       4f

+2:msr     mair_el2, x0

+  b       4f

+3:msr     mair_el3, x0

+4:isb

+  ret

+

+

+//

+//VOID

+//ArmUpdateTranslationTableEntry (

+//  IN VOID  *TranslationTableEntry  // X0

+//  IN VOID  *MVA                    // X1

+//  );

+ASM_PFX(ArmUpdateTranslationTableEntry):

+   dc      civac, x0             // Clean and invalidate data line

+   dsb     sy

+   EL1_OR_EL2_OR_EL3(x0)

+1: tlbi    vaae1, x1             // TLB Invalidate VA , EL1

+   b       4f

+2: tlbi    vae2, x1              // TLB Invalidate VA , EL2

+   b       4f

+3: tlbi    vae3, x1              // TLB Invalidate VA , EL3

+4: dsb     sy

+   isb

+   ret

+

+ASM_PFX(ArmInvalidateTlb):

+   EL1_OR_EL2_OR_EL3(x0)

+1: tlbi  vmalle1

+   b     4f

+2: tlbi  alle2

+   b     4f

+3: tlbi  alle3

+4: dsb   sy

+   isb

+   ret

+

+ASM_PFX(ArmWriteCptr):

+  msr     cptr_el3, x0           // EL3 Coprocessor Trap Reg (CPTR)

+  ret

+

+ASM_PFX(ArmWriteScr):

+  msr     scr_el3, x0            // Secure configuration register EL3

+  ret

+

+ASM_PFX(ArmWriteMVBar):

+  msr    vbar_el3, x0            // Exception Vector Base address for Monitor on EL3

+  ret

+

+ASM_PFX(ArmCallWFE):

+  wfe

+  ret

+

+ASM_PFX(ArmCallSEV):

+  sev

+  ret

+

+ASM_PFX(ArmReadCpuActlr):

+  mrs   x0, S3_1_c15_c2_0

+  ret

+

+ASM_PFX(ArmWriteCpuActlr):

+  msr   S3_1_c15_c2_0, x0

+  dsb   sy

+  isb

+  ret

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
new file mode 100644
index 0000000..43842f3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
@@ -0,0 +1,196 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#include <AsmMacroIoLib.h>

+

+#ifdef ARM_CPU_ARMv6

+// No memory barriers for ARMv6

+#define isb

+#define dsb

+#endif

+

+.text

+.align 2

+GCC_ASM_EXPORT(ArmReadMidr)

+GCC_ASM_EXPORT(ArmCacheInfo)

+GCC_ASM_EXPORT(ArmGetInterruptState)

+GCC_ASM_EXPORT(ArmGetFiqState)

+GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)

+GCC_ASM_EXPORT(ArmSetTTBR0)

+GCC_ASM_EXPORT(ArmSetDomainAccessControl)

+GCC_ASM_EXPORT(CPSRMaskInsert)

+GCC_ASM_EXPORT(CPSRRead)

+GCC_ASM_EXPORT(ArmReadCpacr)

+GCC_ASM_EXPORT(ArmWriteCpacr)

+GCC_ASM_EXPORT(ArmWriteAuxCr)

+GCC_ASM_EXPORT(ArmReadAuxCr)

+GCC_ASM_EXPORT(ArmInvalidateTlb)

+GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)

+GCC_ASM_EXPORT(ArmReadScr)

+GCC_ASM_EXPORT(ArmWriteScr)

+GCC_ASM_EXPORT(ArmReadMVBar)

+GCC_ASM_EXPORT(ArmWriteMVBar)

+GCC_ASM_EXPORT(ArmReadHVBar)

+GCC_ASM_EXPORT(ArmWriteHVBar)

+GCC_ASM_EXPORT(ArmCallWFE)

+GCC_ASM_EXPORT(ArmCallSEV)

+GCC_ASM_EXPORT(ArmReadSctlr)

+GCC_ASM_EXPORT(ArmReadCpuActlr)

+GCC_ASM_EXPORT(ArmWriteCpuActlr)

+

+#------------------------------------------------------------------------------

+

+ASM_PFX(ArmReadMidr):

+  mrc     p15,0,R0,c0,c0,0

+  bx      LR

+

+ASM_PFX(ArmCacheInfo):

+  mrc     p15,0,R0,c0,c0,1

+  bx      LR

+

+ASM_PFX(ArmGetInterruptState):

+  mrs     R0,CPSR

+  tst     R0,#0x80      @Check if IRQ is enabled.

+  moveq   R0,#1

+  movne   R0,#0

+  bx      LR

+

+ASM_PFX(ArmGetFiqState):

+  mrs     R0,CPSR

+  tst     R0,#0x40      @Check if FIQ is enabled.

+  moveq   R0,#1

+  movne   R0,#0

+  bx      LR

+

+ASM_PFX(ArmSetDomainAccessControl):

+  mcr     p15,0,r0,c3,c0,0

+  bx      lr

+

+ASM_PFX(CPSRMaskInsert):    @ on entry, r0 is the mask and r1 is the field to insert

+  stmfd   sp!, {r4-r12, lr} @ save all the banked registers

+  mov     r3, sp            @ copy the stack pointer into a non-banked register

+  mrs     r2, cpsr          @ read the cpsr

+  bic     r2, r2, r0        @ clear mask in the cpsr

+  and     r1, r1, r0        @ clear bits outside the mask in the input

+  orr     r2, r2, r1        @ set field

+  msr     cpsr_cxsf, r2     @ write back cpsr (may have caused a mode switch)

+  isb

+  mov     sp, r3            @ restore stack pointer

+  ldmfd   sp!, {r4-r12, lr} @ restore registers

+  bx      lr                @ return (hopefully thumb-safe!)

+

+ASM_PFX(CPSRRead):

+  mrs     r0, cpsr

+  bx      lr

+

+ASM_PFX(ArmReadCpacr):

+  mrc     p15, 0, r0, c1, c0, 2

+  bx      lr

+

+ASM_PFX(ArmWriteCpacr):

+  mcr     p15, 0, r0, c1, c0, 2

+  isb

+  bx      lr

+

+ASM_PFX(ArmWriteAuxCr):

+  mcr     p15, 0, r0, c1, c0, 1

+  bx      lr

+

+ASM_PFX(ArmReadAuxCr):

+  mrc     p15, 0, r0, c1, c0, 1

+  bx      lr

+

+ASM_PFX(ArmSetTTBR0):

+  mcr     p15,0,r0,c2,c0,0

+  isb

+  bx      lr

+

+ASM_PFX(ArmGetTTBR0BaseAddress):

+  mrc     p15,0,r0,c2,c0,0

+  LoadConstantToReg(0xFFFFC000, r1)

+  and     r0, r0, r1

+  isb

+  bx      lr

+

+//

+//VOID

+//ArmUpdateTranslationTableEntry (

+//  IN VOID  *TranslationTableEntry  // R0

+//  IN VOID  *MVA                    // R1

+//  );

+ASM_PFX(ArmUpdateTranslationTableEntry):

+  mcr     p15,0,R0,c7,c14,1     @ DCCIMVAC Clean data cache by MVA

+  dsb

+  mcr     p15,0,R1,c8,c7,1      @ TLBIMVA TLB Invalidate MVA

+  mcr     p15,0,R9,c7,c5,6      @ BPIALL Invalidate Branch predictor array. R9 == NoOp

+  dsb

+  isb

+  bx      lr

+

+ASM_PFX(ArmInvalidateTlb):

+  mov     r0,#0

+  mcr     p15,0,r0,c8,c7,0

+  mcr     p15,0,R9,c7,c5,6      @ BPIALL Invalidate Branch predictor array. R9 == NoOp

+  dsb

+  isb

+  bx      lr

+

+ASM_PFX(ArmReadScr):

+  mrc     p15, 0, r0, c1, c1, 0

+  bx      lr

+

+ASM_PFX(ArmWriteScr):

+  mcr     p15, 0, r0, c1, c1, 0

+  bx      lr

+

+ASM_PFX(ArmReadHVBar):

+  mrc     p15, 4, r0, c12, c0, 0

+  bx      lr

+

+ASM_PFX(ArmWriteHVBar):

+  mcr     p15, 4, r0, c12, c0, 0

+  bx      lr

+

+ASM_PFX(ArmReadMVBar):

+  mrc     p15, 0, r0, c12, c0, 1

+  bx      lr

+

+ASM_PFX(ArmWriteMVBar):

+  mcr     p15, 0, r0, c12, c0, 1

+  bx      lr

+

+ASM_PFX(ArmCallWFE):

+  wfe

+  bx      lr

+

+ASM_PFX(ArmCallSEV):

+  sev

+  bx      lr

+

+ASM_PFX(ArmReadSctlr):

+  mrc     p15, 0, r0, c1, c0, 0      @ Read SCTLR into R0 (Read control register configuration data)

+  bx      lr

+

+ASM_PFX(ArmReadCpuActlr):

+  mrc     p15, 0, r0, c1, c0, 1

+  bx      lr

+

+ASM_PFX(ArmWriteCpuActlr):

+  mcr     p15, 0, r0, c1, c0, 1

+  dsb

+  isb

+  bx      lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
new file mode 100644
index 0000000..8864c16
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
@@ -0,0 +1,197 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+// 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.

+//

+//------------------------------------------------------------------------------

+

+#include <AsmMacroIoLib.h>

+

+    INCLUDE AsmMacroIoLib.inc

+

+#ifdef ARM_CPU_ARMv6

+// No memory barriers for ARMv6

+#define isb

+#define dsb

+#endif

+

+    EXPORT ArmReadMidr

+    EXPORT ArmCacheInfo

+    EXPORT ArmGetInterruptState

+    EXPORT ArmGetFiqState

+    EXPORT ArmGetTTBR0BaseAddress

+    EXPORT ArmSetTTBR0

+    EXPORT ArmSetDomainAccessControl

+    EXPORT CPSRMaskInsert

+    EXPORT CPSRRead

+    EXPORT ArmReadCpacr

+    EXPORT ArmWriteCpacr

+    EXPORT ArmWriteAuxCr

+    EXPORT ArmReadAuxCr

+    EXPORT ArmInvalidateTlb

+    EXPORT ArmUpdateTranslationTableEntry

+    EXPORT ArmReadScr

+    EXPORT ArmWriteScr

+    EXPORT ArmReadMVBar

+    EXPORT ArmWriteMVBar

+    EXPORT ArmReadHVBar

+    EXPORT ArmWriteHVBar

+    EXPORT ArmCallWFE

+    EXPORT ArmCallSEV

+    EXPORT ArmReadSctlr

+    EXPORT ArmReadCpuActlr

+    EXPORT ArmWriteCpuActlr

+

+    AREA ArmLibSupport, CODE, READONLY

+

+ArmReadMidr

+  mrc     p15,0,R0,c0,c0,0

+  bx      LR

+

+ArmCacheInfo

+  mrc     p15,0,R0,c0,c0,1

+  bx      LR

+

+ArmGetInterruptState

+  mrs     R0,CPSR

+  tst     R0,#0x80      // Check if IRQ is enabled.

+  moveq   R0,#1

+  movne   R0,#0

+  bx      LR

+

+ArmGetFiqState

+  mrs     R0,CPSR

+  tst     R0,#0x40      // Check if FIQ is enabled.

+  moveq   R0,#1

+  movne   R0,#0

+  bx      LR

+

+ArmSetDomainAccessControl

+  mcr     p15,0,r0,c3,c0,0

+  bx      lr

+

+CPSRMaskInsert    // on entry, r0 is the mask and r1 is the field to insert

+  stmfd   sp!, {r4-r12, lr} // save all the banked registers

+  mov     r3, sp            // copy the stack pointer into a non-banked register

+  mrs     r2, cpsr          // read the cpsr

+  bic     r2, r2, r0        // clear mask in the cpsr

+  and     r1, r1, r0        // clear bits outside the mask in the input

+  orr     r2, r2, r1        // set field

+  msr     cpsr_cxsf, r2     // write back cpsr (may have caused a mode switch)

+  isb

+  mov     sp, r3            // restore stack pointer

+  ldmfd   sp!, {r4-r12, lr} // restore registers

+  bx      lr                // return (hopefully thumb-safe!)             // return (hopefully thumb-safe!)

+

+CPSRRead

+  mrs     r0, cpsr

+  bx      lr

+

+ArmReadCpacr

+  mrc     p15, 0, r0, c1, c0, 2

+  bx      lr

+

+ArmWriteCpacr

+  mcr     p15, 0, r0, c1, c0, 2

+  isb

+  bx      lr

+

+ArmWriteAuxCr

+  mcr     p15, 0, r0, c1, c0, 1

+  bx      lr

+

+ArmReadAuxCr

+  mrc     p15, 0, r0, c1, c0, 1

+  bx      lr

+

+ArmSetTTBR0

+  mcr     p15,0,r0,c2,c0,0

+  isb

+  bx      lr

+

+ArmGetTTBR0BaseAddress

+  mrc     p15,0,r0,c2,c0,0

+  LoadConstantToReg(0xFFFFC000, r1)

+  and     r0, r0, r1

+  isb

+  bx      lr

+

+//

+//VOID

+//ArmUpdateTranslationTableEntry (

+//  IN VOID  *TranslationTableEntry  // R0

+//  IN VOID  *MVA                    // R1

+//  );

+ArmUpdateTranslationTableEntry

+  mcr     p15,0,R0,c7,c14,1     // DCCIMVAC Clean data cache by MVA

+  dsb

+  mcr     p15,0,R1,c8,c7,1      // TLBIMVA TLB Invalidate MVA

+  mcr     p15,0,R9,c7,c5,6      // BPIALL Invalidate Branch predictor array. R9 == NoOp

+  dsb

+  isb

+  bx      lr

+

+ArmInvalidateTlb

+  mov     r0,#0

+  mcr     p15,0,r0,c8,c7,0

+  mcr     p15,0,R9,c7,c5,6      // BPIALL Invalidate Branch predictor array. R9 == NoOp

+  dsb

+  isb

+  bx      lr

+

+ArmReadScr

+  mrc     p15, 0, r0, c1, c1, 0

+  bx      lr

+

+ArmWriteScr

+  mcr     p15, 0, r0, c1, c1, 0

+  bx      lr

+

+ArmReadHVBar

+  mrc     p15, 4, r0, c12, c0, 0

+  bx      lr

+

+ArmWriteHVBar

+  mcr     p15, 4, r0, c12, c0, 0

+  bx      lr

+

+ArmReadMVBar

+  mrc     p15, 0, r0, c12, c0, 1

+  bx      lr

+

+ArmWriteMVBar

+  mcr     p15, 0, r0, c12, c0, 1

+  bx      lr

+

+ArmCallWFE

+  wfe

+  bx      lr

+

+ArmCallSEV

+  sev

+  bx      lr

+

+ArmReadSctlr

+  mrc     p15, 0, r0, c1, c0, 0      // Read SCTLR into R0 (Read control register configuration data)

+  bx      lr

+

+

+ArmReadCpuActlr

+  mrc     p15, 0, r0, c1, c0, 1

+  bx      lr

+

+ArmWriteCpuActlr

+  mcr     p15, 0, r0, c1, c0, 1

+  dsb

+  isb

+  bx      lr

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLib.c
new file mode 100644
index 0000000..d731697
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLib.c
@@ -0,0 +1,92 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  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 <Base.h>

+

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+#include "ArmLibPrivate.h"

+

+VOID

+EFIAPI

+ArmCacheInformation (

+  OUT ARM_CACHE_INFO  *CacheInfo

+  )

+{

+  if (CacheInfo != NULL) {

+    CacheInfo->Type                           = ArmCacheType();

+    CacheInfo->Architecture                   = ArmCacheArchitecture();

+    CacheInfo->DataCachePresent               = ArmDataCachePresent();

+    CacheInfo->DataCacheSize                  = ArmDataCacheSize();

+    CacheInfo->DataCacheAssociativity         = ArmDataCacheAssociativity();

+    CacheInfo->DataCacheLineLength            = ArmDataCacheLineLength();

+    CacheInfo->InstructionCachePresent        = ArmInstructionCachePresent();

+    CacheInfo->InstructionCacheSize           = ArmInstructionCacheSize();

+    CacheInfo->InstructionCacheAssociativity  = ArmInstructionCacheAssociativity();

+    CacheInfo->InstructionCacheLineLength     = ArmInstructionCacheLineLength();

+  }

+}

+

+VOID

+EFIAPI

+ArmSetAuxCrBit (

+  IN  UINT32    Bits

+  )

+{

+  UINT32 val = ArmReadAuxCr();

+  val |= Bits;

+  ArmWriteAuxCr(val);

+}

+

+VOID

+EFIAPI

+ArmUnsetAuxCrBit (

+  IN  UINT32    Bits

+  )

+{

+  UINT32 val = ArmReadAuxCr();

+  val &= ~Bits;

+  ArmWriteAuxCr(val);

+}

+

+//

+// Helper functions for accessing CPUACTLR

+//

+

+VOID

+EFIAPI

+ArmSetCpuActlrBit (

+  IN  UINTN    Bits

+  )

+{

+  UINTN Value;

+  Value =  ArmReadCpuActlr ();

+  Value |= Bits;

+  ArmWriteCpuActlr (Value);

+}

+

+VOID

+EFIAPI

+ArmUnsetCpuActlrBit (

+  IN  UINTN    Bits

+  )

+{

+  UINTN Value;

+  Value = ArmReadCpuActlr ();

+  Value &= ~Bits;

+  ArmWriteCpuActlr (Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h
new file mode 100644
index 0000000..fdd5a26
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h
@@ -0,0 +1,80 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __ARM_LIB_PRIVATE_H__

+#define __ARM_LIB_PRIVATE_H__

+

+#define CACHE_SIZE_4_KB             (3UL)

+#define CACHE_SIZE_8_KB             (4UL)

+#define CACHE_SIZE_16_KB            (5UL)

+#define CACHE_SIZE_32_KB            (6UL)

+#define CACHE_SIZE_64_KB            (7UL)

+#define CACHE_SIZE_128_KB           (8UL)

+

+#define CACHE_ASSOCIATIVITY_DIRECT  (0UL)

+#define CACHE_ASSOCIATIVITY_4_WAY   (2UL)

+#define CACHE_ASSOCIATIVITY_8_WAY   (3UL)

+

+#define CACHE_PRESENT               (0UL)

+#define CACHE_NOT_PRESENT           (1UL)

+

+#define CACHE_LINE_LENGTH_32_BYTES  (2UL)

+

+#define SIZE_FIELD_TO_CACHE_SIZE(x)           (((x) >> 6) & 0x0F)

+#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x)  (((x) >> 3) & 0x07)

+#define SIZE_FIELD_TO_CACHE_PRESENCE(x)       (((x) >> 2) & 0x01)

+#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x)    (((x) >> 0) & 0x03)

+

+#define DATA_CACHE_SIZE_FIELD(x)              (((x) >> 12) & 0x0FFF)

+#define INSTRUCTION_CACHE_SIZE_FIELD(x)       (((x) >>  0) & 0x0FFF)

+

+#define DATA_CACHE_SIZE(x)                    (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))

+#define DATA_CACHE_ASSOCIATIVITY(x)           (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))

+#define DATA_CACHE_PRESENT(x)                 (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))

+#define DATA_CACHE_LINE_LENGTH(x)             (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))

+

+#define INSTRUCTION_CACHE_SIZE(x)             (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))

+#define INSTRUCTION_CACHE_ASSOCIATIVITY(x)    (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))

+#define INSTRUCTION_CACHE_PRESENT(x)          (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))

+#define INSTRUCTION_CACHE_LINE_LENGTH(x)      (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))

+

+#define CACHE_TYPE(x)                         (((x) >> 25) & 0x0F)

+#define CACHE_TYPE_WRITE_BACK                 (0x0EUL)

+

+#define CACHE_ARCHITECTURE(x)                 (((x) >> 24) & 0x01)

+#define CACHE_ARCHITECTURE_UNIFIED            (0UL)

+#define CACHE_ARCHITECTURE_SEPARATE           (1UL)

+

+VOID

+CPSRMaskInsert (

+  IN  UINT32  Mask,

+  IN  UINT32  Value

+  );

+

+UINT32

+CPSRRead (

+  VOID

+  );

+

+UINT32

+ReadCCSIDR (

+  IN UINT32 CSSELR

+  );

+

+UINT32

+ReadCLIDR (

+  VOID

+  );

+

+#endif // __ARM_LIB_PRIVATE_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c
new file mode 100644
index 0000000..2eeb42e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c
@@ -0,0 +1,106 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Library/ArmLib.h>

+#include "ArmLibPrivate.h"

+

+ARM_CACHE_TYPE

+EFIAPI

+ArmCacheType (

+  VOID

+  )

+{

+  return ARM_CACHE_TYPE_UNKNOWN;

+}

+

+ARM_CACHE_ARCHITECTURE

+EFIAPI

+ArmCacheArchitecture (

+  VOID

+  )

+{

+  return ARM_CACHE_ARCHITECTURE_UNKNOWN;

+}

+

+BOOLEAN

+EFIAPI

+ArmDataCachePresent (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheSize (

+  VOID

+  )

+{

+  return 0;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheAssociativity (

+  VOID

+  )

+{

+  return 0;

+}

+

+UINTN

+EFIAPI

+ArmDataCacheLineLength (

+  VOID

+  )

+{

+  return 0;

+}

+

+BOOLEAN

+EFIAPI

+ArmInstructionCachePresent (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheSize (

+  VOID

+  )

+{

+  return 0;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheAssociativity (

+  VOID

+  )

+{

+  return 0;

+}

+

+UINTN

+EFIAPI

+ArmInstructionCacheLineLength (

+  VOID

+  )

+{

+  return 0;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.c
new file mode 100644
index 0000000..e7e9c52
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.c
@@ -0,0 +1,117 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Uefi.h>

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmCleanDataCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmInvalidateInstructionCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmInvalidateDataCacheEntryByMVA (

+  IN  UINTN Address

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmCleanDataCacheEntryByMVA (

+  IN  UINTN Address

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmCleanInvalidateDataCacheEntryByMVA (

+  IN  UINTN Address

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmEnableDataCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmDisableDataCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmEnableInstructionCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

+

+VOID

+EFIAPI

+ArmDisableInstructionCache (

+  VOID

+  )

+{

+  // Do not run code using the Null cache library.

+  ASSERT(FALSE);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.inf
new file mode 100644
index 0000000..21c374f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.inf
@@ -0,0 +1,45 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = NullArmLib

+  FILE_GUID                      = 00586300-0E06-4790-AC44-86C56ACBB942

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmLib

+

+[Sources.common]

+  ../Common/ArmLib.c

+

+  NullArmLib.c

+  NullArmCacheInformation.c

+

+[Sources.ARM]

+  ../Common/Arm/ArmLibSupport.S    | GCC

+  ../Common/Arm/ArmLibSupport.asm  | RVCT

+

+[Sources.AARCH64]

+  ../Common/AArch64/ArmLibSupport.S

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
new file mode 100644
index 0000000..df4e113
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
@@ -0,0 +1,96 @@
+/** @file

+  Support ResetSystem Runtime call using PSCI calls

+

+  Note: A similar library is implemented in

+  ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPsciResetSystemLib

+  So similar issues might exist in this implementation too.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>

+  Copyright (c) 2014, 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 <PiDxe.h>

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/EfiResetSystemLib.h>

+#include <Library/ArmSmcLib.h>

+

+#include <IndustryStandard/ArmStdSmc.h>

+

+/**

+  Resets the entire platform.

+

+  @param  ResetType             The type of reset to perform.

+  @param  ResetStatus           The status code for the reset.

+  @param  DataSize              The size, in bytes, of WatchdogData.

+  @param  ResetData             For a ResetType of EfiResetCold, EfiResetWarm, or

+                                EfiResetShutdown the data buffer starts with a Null-terminated

+                                Unicode string, optionally followed by additional binary data.

+

+**/

+EFI_STATUS

+EFIAPI

+LibResetSystem (

+  IN EFI_RESET_TYPE   ResetType,

+  IN EFI_STATUS       ResetStatus,

+  IN UINTN            DataSize,

+  IN CHAR16           *ResetData OPTIONAL

+  )

+{

+  ARM_SMC_ARGS ArmSmcArgs;

+

+  switch (ResetType) {

+  case EfiResetPlatformSpecific:

+    // Map the platform specific reset as reboot

+  case EfiResetWarm:

+    // Map a warm reset into a cold reset

+  case EfiResetCold:

+    // Send a PSCI 0.2 SYSTEM_RESET command

+    ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;

+    break;

+  case EfiResetShutdown:

+    // Send a PSCI 0.2 SYSTEM_OFF command

+    ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;

+    break;

+  default:

+    ASSERT (FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  ArmCallSmc (&ArmSmcArgs);

+

+  // We should never be here

+  DEBUG ((EFI_D_ERROR, "%a: PSCI Reset failed\n", __FUNCTION__));

+  CpuDeadLoop ();

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  Initialize any infrastructure required for LibResetSystem () to function.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+LibInitializeResetSystem (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
new file mode 100644
index 0000000..9cdde1f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
@@ -0,0 +1,37 @@
+#/** @file

+# Reset System lib using PSCI hypervisor or secure monitor calls

+#

+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>

+# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>

+# 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                      = ArmPsciResetSystemLib

+  FILE_GUID                      = A8F59B69-A105-41C7-8F5A-2C60DD7FD7AA

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = EfiResetSystemLib

+

+[Sources]

+  ArmPsciResetSystemLib.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+  ArmSmcLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
new file mode 100644
index 0000000..46c1767
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
@@ -0,0 +1,41 @@
+//

+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials

+//  are licensed and made available under the terms and conditions of the BSD License

+//  which accompanies this distribution.  The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(ArmCallSmc)

+

+ASM_PFX(ArmCallSmc):

+  // Push x0 on the stack - The stack must always be quad-word aligned

+  str   x0, [sp, #-16]!

+

+  // Load the SMC arguments values into the appropriate registers

+  ldp   x6, x7, [x0, #48]

+  ldp   x4, x5, [x0, #32]

+  ldp   x2, x3, [x0, #16]

+  ldp   x0, x1, [x0, #0]

+

+  smc   #0

+

+  // Pop the ARM_SMC_ARGS structure address from the stack into x9

+  ldr   x9, [sp], #16

+

+  // Store the SMC returned values into the ARM_SMC_ARGS structure.

+  // A SMC call can return up to 4 values - we do not need to store back x4-x7.

+  stp   x2, x3, [x9, #16]

+  stp   x0, x1, [x9, #0]

+

+  mov   x0, x9

+

+  ret

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
new file mode 100644
index 0000000..260fb10
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
@@ -0,0 +1,52 @@
+//

+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials

+//  are licensed and made available under the terms and conditions of the BSD License

+//  which accompanies this distribution.  The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+.text

+.align 3

+.arch_extension sec

+

+GCC_ASM_EXPORT(ArmCallSmc)

+

+ASM_PFX(ArmCallSmc):

+    push    {r4-r8}

+    // r0 will be popped just after the SMC call

+    push    {r0}

+

+    // Load the SMC arguments values into the appropriate registers

+    ldr     r7, [r0, #28]

+    ldr     r6, [r0, #24]

+    ldr     r5, [r0, #20]

+    ldr     r4, [r0, #16]

+    ldr     r3, [r0, #12]

+    ldr     r2, [r0, #8]

+    ldr     r1, [r0, #4]

+    ldr     r0, [r0, #0]

+

+    smc     #0

+

+    // Pop the ARM_SMC_ARGS structure address from the stack into r8

+    pop     {r8}

+

+    // Load the SMC returned values into the appropriate registers

+    // A SMC call can return up to 4 values - we do not need to store back r4-r7.

+    str     r3, [r8, #12]

+    str     r2, [r8, #8]

+    str     r1, [r8, #4]

+    str     r0, [r8, #0]

+

+    mov     r0, r8

+

+    // Restore the registers r4-r8

+    pop     {r4-r8}

+

+    bx      lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
new file mode 100644
index 0000000..50580f7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
@@ -0,0 +1,52 @@
+//

+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials

+//  are licensed and made available under the terms and conditions of the BSD License

+//  which accompanies this distribution.  The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+    EXPORT ArmCallSmc

+

+    AREA   ArmSmc, CODE, READONLY

+

+ArmCallSmc

+    push    {r4-r8}

+    // r0 will be popped just after the SMC call

+    push     {r0}

+

+    // Load the SMC arguments values into the appropriate registers

+    ldr     r7, [r0, #28]

+    ldr     r6, [r0, #24]

+    ldr     r5, [r0, #20]

+    ldr     r4, [r0, #16]

+    ldr     r3, [r0, #12]

+    ldr     r2, [r0, #8]

+    ldr     r1, [r0, #4]

+    ldr     r0, [r0, #0]

+

+    smc     #0

+

+    // Pop the ARM_SMC_ARGS structure address from the stack into r8

+    pop     {r8}

+

+    // Load the SMC returned values into the appropriate registers

+    // A SMC call can return up to 4 values - we do not need to store back r4-r7.

+    str     r3, [r8, #12]

+    str     r2, [r8, #8]

+    str     r1, [r8, #4]

+    str     r0, [r8, #0]

+

+    mov     r0, r8

+

+    // Restore the registers r4-r8

+    pop     {r4-r8}

+

+    bx      lr

+

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
new file mode 100644
index 0000000..9f9ba72
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
@@ -0,0 +1,31 @@
+#/** @file

+#

+#  Copyright (c) 2012-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.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmSmcLib

+  FILE_GUID                      = eb3f17d5-a3cc-4eac-8912-84162d0f79da

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmSmcLib

+

+[Sources.ARM]

+  Arm/ArmSmc.asm    | RVCT

+  Arm/ArmSmc.S      | GCC

+

+[Sources.AARCH64]

+  AArch64/ArmSmc.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
new file mode 100644
index 0000000..a6ef0e0
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
@@ -0,0 +1,20 @@
+//

+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials

+//  are licensed and made available under the terms and conditions of the BSD License

+//  which accompanies this distribution.  The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(ArmCallSmc)

+

+ASM_PFX(ArmCallSmc):

+  ret

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
new file mode 100644
index 0000000..9eaefd3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
@@ -0,0 +1,20 @@
+//

+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials

+//  are licensed and made available under the terms and conditions of the BSD License

+//  which accompanies this distribution.  The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(ArmCallSmc)

+

+ASM_PFX(ArmCallSmc):

+  bx     lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
new file mode 100644
index 0000000..3d3f554
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
@@ -0,0 +1,21 @@
+//

+//  Copyright (c) 2012-2014, ARM Limited. All rights reserved.

+//

+//  This program and the accompanying materials

+//  are licensed and made available under the terms and conditions of the BSD License

+//  which accompanies this distribution.  The full text of the license may be found at

+//  http://opensource.org/licenses/bsd-license.php

+//

+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//

+

+    EXPORT ArmCallSmc

+

+    AREA   ArmSmc, CODE, READONLY

+

+ArmCallSmc

+  bx     lr

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
new file mode 100644
index 0000000..6d75c28
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
@@ -0,0 +1,34 @@
+#/** @file

+#

+#  ArmSmcLib when no SMC support is desired (might be the case for CPU without the

+#  Trustzone support / ARM Security Extension)

+#

+#  Copyright (c) 2012-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.

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ArmSmcLibNull

+  FILE_GUID                      = 140e8004-16e1-4de1-a352-c6ef51110ecf

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmSmcLib

+

+[Sources.ARM]

+  Arm/ArmSmcNull.asm    | RVCT

+  Arm/ArmSmcNull.S      | GCC

+

+[Sources.AARCH64]

+  AArch64/ArmSmcNull.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c
new file mode 100644
index 0000000..71ae02a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c
@@ -0,0 +1,146 @@
+/** @file

+

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

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memcpy()

+  //

+  volatile UINT8                    *Destination8;

+  CONST UINT8                       *Source8;

+  volatile UINT32                   *Destination32;

+  CONST UINT32                      *Source32;

+  volatile UINT64                   *Destination64;

+  CONST UINT64                      *Source64;

+  UINTN                             Alignment;

+

+  if ((((UINTN)DestinationBuffer & 0x7) == 0) && (((UINTN)SourceBuffer & 0x7) == 0) && (Length >= 8)) {

+    if (SourceBuffer > DestinationBuffer) {

+      Destination64 = (UINT64*)DestinationBuffer;

+      Source64 = (CONST UINT64*)SourceBuffer;

+      while (Length >= 8) {

+        *(Destination64++) = *(Source64++);

+        Length -= 8;

+      }

+

+      // Finish if there are still some bytes to copy

+      Destination8 = (UINT8*)Destination64;

+      Source8 = (CONST UINT8*)Source64;

+      while (Length-- != 0) {

+        *(Destination8++) = *(Source8++);

+      }

+    } else if (SourceBuffer < DestinationBuffer) {

+      Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);

+      Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);

+

+      // Destination64 and Source64 were aligned on a 64-bit boundary

+      // but if length is not a multiple of 8 bytes then they won't be

+      // anymore.

+

+      Alignment = Length & 0x7;

+      if (Alignment != 0) {

+        Destination8 = (UINT8*)Destination64;

+        Source8 = (CONST UINT8*)Source64;

+

+        while (Alignment-- != 0) {

+          *(--Destination8) = *(--Source8);

+          --Length;

+        }

+        Destination64 = (UINT64*)Destination8;

+        Source64 = (CONST UINT64*)Source8;

+      }

+

+      while (Length > 0) {

+        *(--Destination64) = *(--Source64);

+        Length -= 8;

+      }

+    }

+  } else if ((((UINTN)DestinationBuffer & 0x3) == 0) && (((UINTN)SourceBuffer & 0x3) == 0) && (Length >= 4)) {

+    if (SourceBuffer > DestinationBuffer) {

+      Destination32 = (UINT32*)DestinationBuffer;

+      Source32 = (CONST UINT32*)SourceBuffer;

+      while (Length >= 4) {

+        *(Destination32++) = *(Source32++);

+        Length -= 4;

+      }

+

+      // Finish if there are still some bytes to copy

+      Destination8 = (UINT8*)Destination32;

+      Source8 = (CONST UINT8*)Source32;

+      while (Length-- != 0) {

+        *(Destination8++) = *(Source8++);

+      }

+    } else if (SourceBuffer < DestinationBuffer) {

+      Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);

+      Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);

+

+      // Destination32 and Source32 were aligned on a 32-bit boundary

+      // but if length is not a multiple of 4 bytes then they won't be

+      // anymore.

+

+      Alignment = Length & 0x3;

+      if (Alignment != 0) {

+        Destination8 = (UINT8*)Destination32;

+        Source8 = (CONST UINT8*)Source32;

+

+        while (Alignment-- != 0) {

+          *(--Destination8) = *(--Source8);

+          --Length;

+        }

+        Destination32 = (UINT32*)Destination8;

+        Source32 = (CONST UINT32*)Source8;

+      }

+

+      while (Length > 0) {

+        *(--Destination32) = *(--Source32);

+        Length -= 4;

+      }

+    }

+  } else {

+    if (SourceBuffer > DestinationBuffer) {

+      Destination8 = (UINT8*)DestinationBuffer;

+      Source8 = (CONST UINT8*)SourceBuffer;

+      while (Length-- != 0) {

+        *(Destination8++) = *(Source8++);

+      }

+    } else if (SourceBuffer < DestinationBuffer) {

+      Destination8 = (UINT8*)DestinationBuffer + Length;

+      Source8 = (CONST UINT8*)SourceBuffer + Length;

+      while (Length-- != 0) {

+        *(--Destination8) = *(--Source8);

+      }

+    }

+  }

+  return DestinationBuffer;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/SetMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/SetMem.c
new file mode 100644
index 0000000..368a819
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/SetMem.c
@@ -0,0 +1,84 @@
+/** @file

+

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

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memset()

+  //

+  volatile UINT8                    *Pointer8;

+  volatile UINT32                   *Pointer32;

+  volatile UINT64                   *Pointer64;

+  UINT32                            Value32;

+  UINT64                            Value64;

+

+  if ((((UINTN)Buffer & 0x7) == 0) && (Length >= 8)) {

+    // Generate the 64bit value

+    Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;

+    Value64 = (((UINT64)Value32) << 32) | Value32;

+

+    Pointer64 = (UINT64*)Buffer;

+    while (Length >= 8) {

+      *(Pointer64++) = Value64;

+      Length -= 8;

+    }

+

+    // Finish with bytes if needed

+    Pointer8 = (UINT8*)Pointer64;

+    while (Length-- > 0) {

+      *(Pointer8++) = Value;

+    }

+  } else if ((((UINTN)Buffer & 0x3) == 0) && (Length >= 4)) {

+    // Generate the 32bit value

+    Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;

+

+    Pointer32 = (UINT32*)Buffer;

+    while (Length >= 4) {

+      *(Pointer32++) = Value32;

+      Length -= 4;

+    }

+

+    // Finish with bytes if needed

+    Pointer8 = (UINT8*)Pointer32;

+    while (Length-- > 0) {

+      *(Pointer8++) = Value;

+    }

+  } else {

+    Pointer8 = (UINT8*)Buffer;

+    while (Length-- > 0) {

+      *(Pointer8++) = Value;

+    }

+  }

+  return Buffer;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S
new file mode 100755
index 0000000..7985b59
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S
@@ -0,0 +1,171 @@
+#------------------------------------------------------------------------------

+#

+# CopyMem() worker for ARM

+#

+# This file started out as C code that did 64 bit moves if the buffer was

+# 32-bit aligned, else it does a byte copy. It also does a byte copy for

+# any trailing bytes. It was updated to do 32-byte copies using stm/ldm.

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+/**

+  Copy Length bytes from Source to Destination. Overlap is OK.

+

+  This implementation

+

+  @param  Destination Target of copy

+  @param  Source      Place to copy from

+  @param  Length      Number of bytes to copy

+

+  @return Destination

+

+

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+**/

+.text

+.align 2

+GCC_ASM_EXPORT(InternalMemCopyMem)

+

+ASM_PFX(InternalMemCopyMem):

+  stmfd  sp!, {r4-r11, lr}

+  // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)

+  mov  r11, r0

+  mov  r10, r0

+  mov  r12, r2

+  mov  r14, r1

+

+memcopy_check_overlapped:

+  cmp  r11, r1

+  // If (dest < source)

+  bcc  memcopy_check_optim_default

+  // If (dest <= source). But with the previous condition ->  If (dest == source)

+  bls  memcopy_end

+

+  // If (source + length < dest)

+  rsb  r3, r1, r11

+  cmp  r12, r3

+  bcc  memcopy_check_optim_default

+

+  // If (length == 0)

+  cmp  r12, #0

+  beq  memcopy_end

+

+  b     memcopy_check_optim_overlap

+

+memcopy_check_optim_default:

+  // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)

+  tst  r0, #0xF

+  movne  r0, #0

+  bne   memcopy_default

+  tst  r1, #0xF

+  movne  r3, #0

+  moveq  r3, #1

+  cmp  r2, #31

+  movls  r0, #0

+  andhi  r0, r3, #1

+  b     memcopy_default

+

+memcopy_check_optim_overlap:

+  // r10 = dest_end, r14 = source_end

+  add  r10, r11, r12

+  add  r14, r12, r1

+

+  // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)

+  cmp  r2, #31

+  movls  r0, #0

+  movhi  r0, #1

+  tst  r10, #0xF

+  movne  r0, #0

+  tst  r14, #0xF

+  movne  r0, #0

+  b  memcopy_overlapped

+

+memcopy_overlapped_non_optim:

+  // We read 1 byte from the end of the source buffer

+  sub  r3, r14, #1

+  sub  r12, r12, #1

+  ldrb  r3, [r3, #0]

+  sub  r2, r10, #1

+  cmp  r12, #0

+  // We write 1 byte at the end of the dest buffer

+  sub  r10, r10, #1

+  sub  r14, r14, #1

+  strb  r3, [r2, #0]

+  bne  memcopy_overlapped_non_optim

+  b   memcopy_end

+

+// r10 = dest_end, r14 = source_end

+memcopy_overlapped:

+  // Are we in the optimized case ?

+  cmp  r0, #0

+  beq  memcopy_overlapped_non_optim

+

+  // Optimized Overlapped - Read 32 bytes

+  sub  r14, r14, #32

+  sub  r12, r12, #32

+  cmp  r12, #31

+  ldmia  r14, {r2-r9}

+

+  // If length is less than 32 then disable optim

+  movls  r0, #0

+

+  cmp  r12, #0

+

+  // Optimized Overlapped - Write 32 bytes

+  sub  r10, r10, #32

+  stmia  r10, {r2-r9}

+

+  // while (length != 0)

+  bne  memcopy_overlapped

+  b   memcopy_end

+

+memcopy_default_non_optim:

+  // Byte copy

+  ldrb  r3, [r14], #1

+  sub  r12, r12, #1

+  strb  r3, [r10], #1

+

+memcopy_default:

+  cmp  r12, #0

+  beq  memcopy_end

+

+// r10 = dest, r14 = source

+memcopy_default_loop:

+  cmp  r0, #0

+  beq  memcopy_default_non_optim

+

+  // Optimized memcopy - Read 32 Bytes

+  sub  r12, r12, #32

+  cmp  r12, #31

+  ldmia  r14!, {r2-r9}

+

+  // If length is less than 32 then disable optim

+  movls  r0, #0

+

+  cmp  r12, #0

+

+  // Optimized memcopy - Write 32 Bytes

+  stmia  r10!, {r2-r9}

+

+  // while (length != 0)

+  bne  memcopy_default_loop

+

+memcopy_end:

+  mov  r0, r11

+  ldmfd  sp!, {r4-r11, pc}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.asm
new file mode 100755
index 0000000..0d22d75
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.asm
@@ -0,0 +1,173 @@
+;------------------------------------------------------------------------------

+;

+; CopyMem() worker for ARM

+;

+; This file started out as C code that did 64 bit moves if the buffer was

+; 32-bit aligned, else it does a byte copy. It also does a byte copy for

+; any trailing bytes. It was updated to do 32-byte copies using stm/ldm.

+;

+; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+; This program and the accompanying materials

+; are licensed and made available under the terms and conditions of the BSD License

+; which accompanies this distribution.  The full text of the license may be found at

+; http://opensource.org/licenses/bsd-license.php

+;

+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+;

+;------------------------------------------------------------------------------

+

+/**

+  Copy Length bytes from Source to Destination. Overlap is OK.

+

+  This implementation

+

+  @param  Destination Target of copy

+  @param  Source      Place to copy from

+  @param  Length      Number of bytes to copy

+

+  @return Destination

+

+

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+**/

+  EXPORT InternalMemCopyMem

+

+  AREA AsmMemStuff, CODE, READONLY

+

+InternalMemCopyMem

+  stmfd  sp!, {r4-r11, lr}

+  // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)

+  mov  r11, r0

+  mov  r10, r0

+  mov  r12, r2

+  mov  r14, r1

+

+memcopy_check_overlapped

+  cmp  r11, r1

+  // If (dest < source)

+  bcc  memcopy_check_optim_default

+  // If (dest <= source). But with the previous condition ->  If (dest == source)

+  bls  memcopy_end

+

+  // If (source + length < dest)

+  rsb  r3, r1, r11

+  cmp  r12, r3

+  bcc  memcopy_check_optim_default

+

+  // If (length == 0)

+  cmp  r12, #0

+  beq  memcopy_end

+

+  b     memcopy_check_optim_overlap

+

+memcopy_check_optim_default

+  // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)

+  tst  r0, #0xF

+  movne  r0, #0

+  bne   memcopy_default

+  tst  r1, #0xF

+  movne  r3, #0

+  moveq  r3, #1

+  cmp  r2, #31

+  movls  r0, #0

+  andhi  r0, r3, #1

+  b     memcopy_default

+

+memcopy_check_optim_overlap

+  // r10 = dest_end, r14 = source_end

+  add  r10, r11, r12

+  add  r14, r12, r1

+

+  // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)

+  cmp  r2, #31

+  movls  r0, #0

+  movhi  r0, #1

+  tst  r10, #0xF

+  movne  r0, #0

+  tst  r14, #0xF

+  movne  r0, #0

+  b  memcopy_overlapped

+

+memcopy_overlapped_non_optim

+  // We read 1 byte from the end of the source buffer

+  sub  r3, r14, #1

+  sub  r12, r12, #1

+  ldrb  r3, [r3, #0]

+  sub  r2, r10, #1

+  cmp  r12, #0

+  // We write 1 byte at the end of the dest buffer

+  sub  r10, r10, #1

+  sub  r14, r14, #1

+  strb  r3, [r2, #0]

+  bne  memcopy_overlapped_non_optim

+  b   memcopy_end

+

+// r10 = dest_end, r14 = source_end

+memcopy_overlapped

+  // Are we in the optimized case ?

+  cmp  r0, #0

+  beq  memcopy_overlapped_non_optim

+

+  // Optimized Overlapped - Read 32 bytes

+  sub  r14, r14, #32

+  sub  r12, r12, #32

+  cmp  r12, #31

+  ldmia  r14, {r2-r9}

+

+  // If length is less than 32 then disable optim

+  movls  r0, #0

+

+  cmp  r12, #0

+

+  // Optimized Overlapped - Write 32 bytes

+  sub  r10, r10, #32

+  stmia  r10, {r2-r9}

+

+  // while (length != 0)

+  bne  memcopy_overlapped

+  b   memcopy_end

+

+memcopy_default_non_optim

+  // Byte copy

+  ldrb  r3, [r14], #1

+  sub  r12, r12, #1

+  strb  r3, [r10], #1

+

+memcopy_default

+  cmp  r12, #0

+  beq  memcopy_end

+

+// r10 = dest, r14 = source

+memcopy_default_loop

+  cmp  r0, #0

+  beq  memcopy_default_non_optim

+

+  // Optimized memcopy - Read 32 Bytes

+  sub  r12, r12, #32

+  cmp  r12, #31

+  ldmia  r14!, {r2-r9}

+

+  // If length is less than 32 then disable optim

+  movls  r0, #0

+

+  cmp  r12, #0

+

+  // Optimized memcopy - Write 32 Bytes

+  stmia  r10!, {r2-r9}

+

+  // while (length != 0)

+  bne  memcopy_default_loop

+

+memcopy_end

+  mov  r0, r11

+  ldmfd  sp!, {r4-r11, pc}

+

+  END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S
new file mode 100755
index 0000000..c5b4cfe
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S
@@ -0,0 +1,81 @@
+#------------------------------------------------------------------------------

+#

+# SemMem() worker for ARM

+#

+# This file started out as C code that did 64 bit moves if the buffer was

+# 32-bit aligned, else it does a byte copy. It also does a byte copy for

+# any trailing bytes. It was updated to do 32-byte at a time.

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+**/

+

+.text

+.align 2

+GCC_ASM_EXPORT(InternalMemSetMem)

+

+ASM_PFX(InternalMemSetMem):

+  stmfd  sp!, {r4-r11, lr}

+  tst    r0, #3

+  movne  r3, #0

+  moveq  r3, #1

+  cmp    r1, #31

+  movls lr, #0

+  andhi  lr, r3, #1

+  cmp    lr, #0

+  mov    r12, r0

+  bne    L31

+L32:

+  mov    r3, #0

+  b      L43

+L31:

+  and   r4, r2, #0xff

+  orr   r4, r4, r4, LSL #8

+  orr   r4, r4, r4, LSL #16

+  mov   r5, r4

+  mov   r6, r4

+  mov   r7, r4

+  mov   r8, r4

+  mov   r9, r4

+  mov   r10, r4

+  mov   r11, r4

+  b      L32

+L34:

+  cmp      lr, #0

+  streqb  r2, [r12], #1

+  subeq    r1, r1, #1

+  beq      L43

+  sub      r1, r1, #32

+  cmp      r1, #31

+  movls    lr, r3

+  stmia    r12!, {r4-r11}

+L43:

+  cmp      r1, #0

+  bne      L34

+  ldmfd    sp!, {r4-r11, pc}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.asm
new file mode 100755
index 0000000..a9f29e2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.asm
@@ -0,0 +1,81 @@
+;------------------------------------------------------------------------------

+;

+; SetMem() worker for ARM

+;

+; This file started out as C code that did 64 bit moves if the buffer was

+; 32-bit aligned, else it does a byte copy. It also does a byte copy for

+; any trailing bytes. It was updated to do 32-byte at a time.

+;

+; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+; This program and the accompanying materials

+; are licensed and made available under the terms and conditions of the BSD License

+; which accompanies this distribution.  The full text of the license may be found at

+; http://opensource.org/licenses/bsd-license.php

+;

+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+;

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+**/

+

+  EXPORT InternalMemSetMem

+

+  AREA AsmMemStuff, CODE, READONLY

+

+InternalMemSetMem

+  stmfd  sp!, {r4-r11, lr}

+  tst    r0, #3

+  movne  r3, #0

+  moveq  r3, #1

+  cmp    r1, #31

+  movls lr, #0

+  andhi  lr, r3, #1

+  cmp    lr, #0

+  mov    r12, r0

+  bne    L31

+L32

+  mov    r3, #0

+  b      L43

+L31

+  and   r4, r2, #0xff

+  orr   r4, r4, r4, LSL #8

+  orr   r4, r4, r4, LSL #16

+  mov   r5, r4

+  mov   r6, r4

+  mov   r7, r4

+  mov   r8, r4

+  mov   r9, r4

+  mov   r10, r4

+  mov   r11, r4

+  b      L32

+L34

+  cmp      lr, #0

+  streqb  r2, [r12], #1

+  subeq    r1, r1, #1

+  beq      L43

+  sub      r1, r1, #32

+  cmp      r1, #31

+  movls    lr, r3

+  stmia    r12!, {r4-r11}

+L43

+  cmp      r1, #0

+  bne      L34

+  ldmfd    sp!, {r4-r11, pc}

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
new file mode 100755
index 0000000..c2f3e2f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
@@ -0,0 +1,68 @@
+## @file

+#  Instance of Base Memory Library with some ARM ldm/stm assembly.

+#

+#  This is a copy of the MdePkg BaseMemoryLib with the CopyMem and

+#  SetMem worker functions replaced with assembler that uses

+#  ldm/stm.

+#

+#  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>

+#  Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+#  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibStm

+  FILE_GUID                      = 4D466AF3-2380-448D-A337-E4033F29F3F7

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib

+

+

+#

+#  VALID_ARCHITECTURES           = ARM AARCH64

+#

+

+

+[Sources.Common]

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGeneric.c

+  MemLibGuid.c

+  MemLibInternals.h

+

+[Sources.ARM]

+  Arm/CopyMem.asm

+  Arm/CopyMem.S

+  Arm/SetMem.asm

+  Arm/SetMem.S

+

+[Sources.AARCH64]

+  AArch64/CopyMem.c

+  AArch64/SetMem.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CompareMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CompareMemWrapper.c
new file mode 100755
index 0000000..c83988f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Compares the contents of two buffers.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.

+  If all Length bytes of the two buffers are identical, then 0 is returned.  Otherwise, the

+  value returned is the first mismatched byte in SourceBuffer subtracted from the first

+  mismatched byte in DestinationBuffer.

+

+  If Length > 0 and DestinationBuffer is NULL, then ASSERT().

+  If Length > 0 and SourceBuffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer Pointer to the destination buffer to compare.

+  @param  SourceBuffer      Pointer to the source buffer to compare.

+  @param  Length            Number of bytes to compare.

+

+  @return 0                 All Length bytes of the two buffers are identical.

+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first

+                            mismatched byte in DestinationBuffer.

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN CONST VOID  *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMem.c
new file mode 100755
index 0000000..b30faed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMem.c
@@ -0,0 +1,62 @@
+/** @file

+  Implementation of the InternalMemCopyMem routine. This function is broken

+  out into its own source file so that it can be excluded from a build for a

+  particular platform easily if an optimized version is desired.

+

+  Copyright (c) 2006 - 2008, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memcpy()

+  //

+  volatile UINT8                    *Destination8;

+  CONST UINT8                       *Source8;

+

+  if (SourceBuffer > DestinationBuffer) {

+    Destination8 = (UINT8*)DestinationBuffer;

+    Source8 = (CONST UINT8*)SourceBuffer;

+    while (Length-- != 0) {

+      *(Destination8++) = *(Source8++);

+    }

+  } else if (SourceBuffer < DestinationBuffer) {

+    Destination8 = (UINT8*)DestinationBuffer + Length;

+    Source8 = (CONST UINT8*)SourceBuffer + Length;

+    while (Length-- != 0) {

+      *(--Destination8) = *(--Source8);

+    }

+  }

+  return DestinationBuffer;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMemWrapper.c
new file mode 100755
index 0000000..2adfb31
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Copies a source buffer to a destination buffer, and returns the destination buffer.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and returns

+  DestinationBuffer.  The implementation must be reentrant, and it must handle the case

+  where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer   Pointer to the destination buffer of the memory copy.

+  @param  SourceBuffer        Pointer to the source buffer of the memory copy.

+  @param  Length              Number of bytes to copy from SourceBuffer to DestinationBuffer.

+

+  @return DestinationBuffer.

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT VOID       *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c
new file mode 100755
index 0000000..ef78748
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c
@@ -0,0 +1,260 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 16-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 32-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 64-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @return 0                 All Length bytes of the two buffers are identical.

+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first

+                            mismatched byte in DestinationBuffer.

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 8-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 16-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 32-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 64-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c
new file mode 100755
index 0000000..2b4ed57
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c
@@ -0,0 +1,132 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid to

+  DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid   Pointer to the destination GUID.

+  @param  SourceGuid        Pointer to the source GUID.

+

+  @return DestinationGuid.

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT GUID       *DestinationGuid,

+  IN CONST GUID  *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs.

+

+  This function compares Guid1 to Guid2.  If the GUIDs are identical then TRUE is returned.

+  If there are any bit differences in the two GUIDs, then FALSE is returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1       A pointer to a 128 bit GUID.

+  @param  Guid2       A pointer to a 128 bit GUID.

+

+  @retval TRUE        Guid1 and Guid2 are identical.

+  @retval FALSE       Guid1 and Guid2 are not identical.

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN CONST GUID  *Guid1,

+  IN CONST GUID  *Guid2

+  )

+{

+  return (CompareMem(Guid1, Guid2, sizeof(GUID)) == 0) ? TRUE : FALSE;

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the 128-bit

+  GUID value that matches Guid.  If a match is found, then a pointer to the matching

+  GUID in the target buffer is returned.  If no match is found, then NULL is returned.

+  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 128-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return A pointer to the matching Guid in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h
new file mode 100755
index 0000000..10c741f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 16-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 32-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 64-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @return 0                 All Length bytes of the two buffers are identical.

+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first

+                            mismatched byte in DestinationBuffer.

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 8-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 16-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 32-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 64-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem16Wrapper.c
new file mode 100755
index 0000000..1c727b3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the matching 16-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a 16-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem32Wrapper.c
new file mode 100755
index 0000000..79ab60c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the matching 32-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a 32-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem64Wrapper.c
new file mode 100755
index 0000000..d11e50b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the matching 64-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a 64-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem8Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem8Wrapper.c
new file mode 100755
index 0000000..c6c6d5f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the matching 8-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for an 8-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

+

+/**

+  Scans a target buffer for a UINTN sized value, and returns a pointer to the matching

+  UINTN sized value in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a UINTN sized value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a UINTN boundary, then ASSERT().

+  If Length is not aligned on a UINTN boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem.c
new file mode 100755
index 0000000..5c30e9b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem.c
@@ -0,0 +1,53 @@
+/** @file

+  Implementation of the EfiSetMem routine. This function is broken

+  out into its own source file so that it can be excluded from a

+  build for a particular platform easily if an optimized version

+  is desired.

+

+  Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memset()

+  //

+  volatile UINT8                    *Pointer;

+

+  Pointer = (UINT8*)Buffer;

+  while (Length-- > 0) {

+    *(Pointer++) = Value;

+  }

+  return Buffer;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem16Wrapper.c
new file mode 100755
index 0000000..8129d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT VOID   *Buffer,

+  IN UINTN   Length,

+  IN UINT16  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem32Wrapper.c
new file mode 100755
index 0000000..b57ba40
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT VOID   *Buffer,

+  IN UINTN   Length,

+  IN UINT32  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem64Wrapper.c
new file mode 100755
index 0000000..f979580
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT VOID   *Buffer,

+  IN UINTN   Length,

+  IN UINT64  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMemWrapper.c
new file mode 100755
index 0000000..9240c89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a byte value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer    Memory to set.

+  @param  Length    Number of bytes to set.

+  @param  Value     Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  OUT VOID  *Buffer,

+  IN UINTN  Length,

+  IN UINT8  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, Value);

+}

+

+/**

+  Fills a target buffer with a value that is size UINTN, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the UINTN sized value specified by

+  Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a UINTN boundary, then ASSERT().

+  If Length is not aligned on a UINTN boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMemN (

+  OUT VOID  *Buffer,

+  IN UINTN  Length,

+  IN UINTN  Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ZeroMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ZeroMemWrapper.c
new file mode 100755
index 0000000..d6c6279
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with zeros, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to fill with zeros.

+  @param  Length      Number of bytes in Buffer to fill with zeros.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
new file mode 100755
index 0000000..0a6e039
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
@@ -0,0 +1,114 @@
+#------------------------------------------------------------------------------

+#

+# CopyMem() worker for ARM

+#

+# This file started out as C code that did 64 bit moves if the buffer was

+# 32-bit aligned, else it does a byte copy. It also does a byte copy for

+# any trailing bytes. Update using VSTM/SLDM to do 128 byte copies.

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+/**

+  Copy Length bytes from Source to Destination. Overlap is OK.

+

+  This implementation

+

+  @param  Destination Target of copy

+  @param  Source      Place to copy from

+  @param  Length      Number of bytes to copy

+

+  @return Destination

+

+

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+**/

+.text

+.align 2

+GCC_ASM_EXPORT(InternalMemCopyMem)

+

+ASM_PFX(InternalMemCopyMem):

+  stmfd  sp!, {r4, r9, lr}

+  tst  r0, #3

+  mov  r4, r0

+  mov  r9, r0

+  mov  ip, r2

+  mov  lr, r1

+  movne  r0, #0

+  bne  L4

+  tst  r1, #3

+  movne  r3, #0

+  moveq  r3, #1

+  cmp  r2, #127

+  movls  r0, #0

+  andhi  r0, r3, #1

+L4:

+  cmp  r4, r1

+  bcc  L26

+  bls  L7

+  rsb  r3, r1, r4

+  cmp  ip, r3

+  bcc  L26

+  cmp  ip, #0

+  beq  L7

+  add  r9, r4, ip

+  add  lr, ip, r1

+  b  L16

+L29:

+  sub  ip, ip, #8

+  cmp  ip, #7

+  ldrd  r2, [lr, #-8]!

+  movls  r0, #0

+  cmp  ip, #0

+  strd  r2, [r9, #-8]!

+  beq  L7

+L16:

+  cmp  r0, #0

+  bne  L29

+  sub  r3, lr, #1

+  sub  ip, ip, #1

+  ldrb  r3, [r3, #0]

+  sub  r2, r9, #1

+  cmp  ip, #0

+  sub  r9, r9, #1

+  sub  lr, lr, #1

+  strb  r3, [r2, #0]

+  bne  L16

+  b   L7

+L11:

+  ldrb  r3, [lr], #1

+  sub  ip, ip, #1

+  strb  r3, [r9], #1

+L26:

+  cmp  ip, #0

+  beq  L7

+L30:

+  cmp  r0, #0

+  beq  L11

+  sub  ip, ip, #128          // 32

+  cmp  ip, #127              // 31

+  vldm     lr!, {d0-d15}

+  movls  r0, #0

+  cmp  ip, #0

+  vstm  r9!, {d0-d15}

+  bne  L30

+L7:

+  dsb

+  mov  r0, r4

+  ldmfd  sp!, {r4, r9, pc}

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm
new file mode 100755
index 0000000..17b79e5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm
@@ -0,0 +1,115 @@
+;------------------------------------------------------------------------------

+;

+; CopyMem() worker for ARM

+;

+; This file started out as C code that did 64 bit moves if the buffer was

+; 32-bit aligned, else it does a byte copy. It also does a byte copy for

+; any trailing bytes. Update using VSTM/SLDM to do 128 byte copies.

+;

+; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+; This program and the accompanying materials

+; are licensed and made available under the terms and conditions of the BSD License

+; which accompanies this distribution.  The full text of the license may be found at

+; http://opensource.org/licenses/bsd-license.php

+;

+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+;

+;------------------------------------------------------------------------------

+

+/**

+  Copy Length bytes from Source to Destination. Overlap is OK.

+

+  This implementation

+

+  @param  Destination Target of copy

+  @param  Source      Place to copy from

+  @param  Length      Number of bytes to copy

+

+  @return Destination

+

+

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+**/

+  EXPORT InternalMemCopyMem

+

+  AREA AsmMemStuff, CODE, READONLY

+

+InternalMemCopyMem

+  stmfd  sp!, {r4, r9, lr}

+  tst  r0, #3

+  mov  r4, r0

+  mov  r9, r0

+  mov  ip, r2

+  mov  lr, r1

+  movne  r0, #0

+  bne  L4

+  tst  r1, #3

+  movne  r3, #0

+  moveq  r3, #1

+  cmp  r2, #127

+  movls  r0, #0

+  andhi  r0, r3, #1

+L4

+  cmp  r4, r1

+  bcc  L26

+  bls  L7

+  rsb  r3, r1, r4

+  cmp  ip, r3

+  bcc  L26

+  cmp  ip, #0

+  beq  L7

+  add  r9, r4, ip

+  add  lr, ip, r1

+  b  L16

+L29

+  sub  ip, ip, #8

+  cmp  ip, #7

+  ldrd  r2, [lr, #-8]!

+  movls  r0, #0

+  cmp  ip, #0

+  strd  r2, [r9, #-8]!

+  beq  L7

+L16

+  cmp  r0, #0

+  bne  L29

+  sub  r3, lr, #1

+  sub  ip, ip, #1

+  ldrb  r3, [r3, #0]

+  sub  r2, r9, #1

+  cmp  ip, #0

+  sub  r9, r9, #1

+  sub  lr, lr, #1

+  strb  r3, [r2, #0]

+  bne  L16

+  b   L7

+L11

+  ldrb  r3, [lr], #1

+  sub  ip, ip, #1

+  strb  r3, [r9], #1

+L26

+  cmp  ip, #0

+  beq  L7

+L30

+  cmp  r0, #0

+  beq  L11

+  sub  ip, ip, #128          // 32

+  cmp  ip, #127              // 31

+  vldm     lr!, {d0-d15}

+  movls  r0, #0

+  cmp  ip, #0

+  vstm  r9!, {d0-d15}

+  bne  L30

+L7

+  dsb

+  mov  r0, r4

+  ldmfd  sp!, {r4, r9, pc}

+

+  END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
new file mode 100755
index 0000000..6a6bb20
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
@@ -0,0 +1,79 @@
+#------------------------------------------------------------------------------

+#

+# SemMem() worker for ARM

+#

+# This file started out as C code that did 64 bit moves if the buffer was

+# 32-bit aligned, else it does a byte copy. It also does a byte copy for

+# any trailing bytes. Update to use VSTM/VLDM to do 128 byte writes.

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+**/

+

+.text

+.align 2

+GCC_ASM_EXPORT(InternalMemSetMem)

+

+ASM_PFX(InternalMemSetMem):

+  stmfd  sp!, {r4-r7, lr}

+  tst    r0, #3

+  movne  r3, #0

+  moveq  r3, #1

+  cmp    r1, #127

+  movls lr, #0

+  andhi  lr, r3, #1

+  cmp    lr, #0

+  mov    r12, r0

+  bne    L31

+L32:

+  mov    r3, #0

+  b      L43

+L31:

+  vdup.8  q0,r2

+  vmov    q1,q0

+  vmov    q2,q0

+  vmov    q3,q0

+  vmov    q4,q0

+  vmov    q5,q0

+  vmov    q6,q0

+  vmov    q7,q0

+  b        L32

+L34:

+  cmp      lr, #0

+  streqb  r2, [r12], #1

+  subeq    r1, r1, #1

+  beq      L43

+  sub      r1, r1, #128

+  cmp      r1, #127

+  cmp      r1, #31

+  movls    lr, r3

+  vstm    r12!, {d0-d15}

+L43:

+  cmp      r1, #0

+  bne      L34

+  ldmfd    sp!, {pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm
new file mode 100755
index 0000000..5226192
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------

+;

+; SetMem() worker for ARM

+;

+; This file started out as C code that did 64 bit moves if the buffer was

+; 32-bit aligned, else it does a byte copy. It also does a byte copy for

+; any trailing bytes. Update to use VSTM/VLDM to do 128 byte writes.

+;

+; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+; This program and the accompanying materials

+; are licensed and made available under the terms and conditions of the BSD License

+; which accompanies this distribution.  The full text of the license may be found at

+; http://opensource.org/licenses/bsd-license.php

+;

+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+;

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+**/

+

+  EXPORT InternalMemSetMem

+

+  AREA AsmMemStuff, CODE, READONLY

+

+InternalMemSetMem

+  stmfd  sp!, {lr}

+  tst    r0, #3

+  movne  r3, #0

+  moveq  r3, #1

+  cmp    r1, #127

+  movls lr, #0

+  andhi  lr, r3, #1

+  cmp    lr, #0

+  mov    r12, r0

+  bne    L31

+L32

+  mov    r3, #0

+  b      L43

+L31

+  vdup.8  q0,r2

+  vmov    q1,q0

+  vmov    q2,q0

+  vmov    q3,q0

+  vmov    q4,q0

+  vmov    q5,q0

+  vmov    q6,q0

+  vmov    q7,q0

+  b        L32

+L34

+  cmp      lr, #0

+  streqb  r2, [r12], #1

+  subeq    r1, r1, #1

+  beq      L43

+  sub      r1, r1, #128

+  cmp      r1, #127

+  movls    lr, r3

+  vstm    r12!, {d0-d15}

+L43

+  cmp      r1, #0

+  bne      L34

+  ldmfd    sp!, {pc}

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
new file mode 100755
index 0000000..eaff180
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
@@ -0,0 +1,69 @@
+## @file

+#  Instance of Base Memory Library with some ARM vldm/vstm assembly.

+#

+#  This is a copy of the MdePkg BaseMemoryLib with the CopyMem and

+#  SetMem worker functions replaced with assembler that uses

+#  vldm/vstm (part of NEON SIMD, optional in ARMv7-A).

+#

+#  Note: You need to enable NEON in SEC to use this library

+#  // Enable NEON register in case folks want to use them for optimizations (CopyMem)

+#  mrc     p15, 0, r0, c1, c0, 2

+#  orr     r0, r0, #0x00f00000   // Enable VPF access (V* instructions)

+#  mcr     p15, 0, r0, c1, c0, 2

+#  mov     r0, #0x40000000       // Set EN bit in FPEXC

+#  msr     FPEXC,r0

+#

+#  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>

+#  Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibVstm

+  FILE_GUID                      = 09EE1E8D-7A2E-4573-8117-68A18569C1F5

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib

+

+

+#

+#  VALID_ARCHITECTURES           = ARM

+#

+

+[Sources.ARM]

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGeneric.c

+  MemLibGuid.c

+  MemLibInternals.h

+  Arm/CopyMem.asm

+  Arm/CopyMem.S

+  Arm/SetMem.asm

+  Arm/SetMem.S

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c
new file mode 100755
index 0000000..c83988f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Compares the contents of two buffers.

+

+  This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.

+  If all Length bytes of the two buffers are identical, then 0 is returned.  Otherwise, the

+  value returned is the first mismatched byte in SourceBuffer subtracted from the first

+  mismatched byte in DestinationBuffer.

+

+  If Length > 0 and DestinationBuffer is NULL, then ASSERT().

+  If Length > 0 and SourceBuffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer Pointer to the destination buffer to compare.

+  @param  SourceBuffer      Pointer to the source buffer to compare.

+  @param  Length            Number of bytes to compare.

+

+  @return 0                 All Length bytes of the two buffers are identical.

+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first

+                            mismatched byte in DestinationBuffer.

+

+**/

+INTN

+EFIAPI

+CompareMem (

+  IN CONST VOID  *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c
new file mode 100755
index 0000000..b30faed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c
@@ -0,0 +1,62 @@
+/** @file

+  Implementation of the InternalMemCopyMem routine. This function is broken

+  out into its own source file so that it can be excluded from a build for a

+  particular platform easily if an optimized version is desired.

+

+  Copyright (c) 2006 - 2008, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memcpy()

+  //

+  volatile UINT8                    *Destination8;

+  CONST UINT8                       *Source8;

+

+  if (SourceBuffer > DestinationBuffer) {

+    Destination8 = (UINT8*)DestinationBuffer;

+    Source8 = (CONST UINT8*)SourceBuffer;

+    while (Length-- != 0) {

+      *(Destination8++) = *(Source8++);

+    }

+  } else if (SourceBuffer < DestinationBuffer) {

+    Destination8 = (UINT8*)DestinationBuffer + Length;

+    Source8 = (CONST UINT8*)SourceBuffer + Length;

+    while (Length-- != 0) {

+      *(--Destination8) = *(--Source8);

+    }

+  }

+  return DestinationBuffer;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c
new file mode 100755
index 0000000..2adfb31
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Copies a source buffer to a destination buffer, and returns the destination buffer.

+

+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and returns

+  DestinationBuffer.  The implementation must be reentrant, and it must handle the case

+  where SourceBuffer overlaps DestinationBuffer.

+

+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().

+

+  @param  DestinationBuffer   Pointer to the destination buffer of the memory copy.

+  @param  SourceBuffer        Pointer to the source buffer of the memory copy.

+  @param  Length              Number of bytes to copy from SourceBuffer to DestinationBuffer.

+

+  @return DestinationBuffer.

+

+**/

+VOID *

+EFIAPI

+CopyMem (

+  OUT VOID       *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c
new file mode 100755
index 0000000..ef78748
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c
@@ -0,0 +1,260 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 16-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 32-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 64-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @return 0                 All Length bytes of the two buffers are identical.

+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first

+                            mismatched byte in DestinationBuffer.

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 8-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 16-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 32-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 64-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c
new file mode 100755
index 0000000..dc9e2c3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c
@@ -0,0 +1,132 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Copies a source GUID to a destination GUID.

+

+  This function copies the contents of the 128-bit GUID specified by SourceGuid to

+  DestinationGuid, and returns DestinationGuid.

+

+  If DestinationGuid is NULL, then ASSERT().

+  If SourceGuid is NULL, then ASSERT().

+

+  @param  DestinationGuid   Pointer to the destination GUID.

+  @param  SourceGuid        Pointer to the source GUID.

+

+  @return DestinationGuid.

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT GUID       *DestinationGuid,

+  IN CONST GUID  *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  Compares two GUIDs.

+

+  This function compares Guid1 to Guid2.  If the GUIDs are identical then TRUE is returned.

+  If there are any bit differences in the two GUIDs, then FALSE is returned.

+

+  If Guid1 is NULL, then ASSERT().

+  If Guid2 is NULL, then ASSERT().

+

+  @param  Guid1       A pointer to a 128 bit GUID.

+  @param  Guid2       A pointer to a 128 bit GUID.

+

+  @retval TRUE        Guid1 and Guid2 are identical.

+  @retval FALSE       Guid1 and Guid2 are not identical.

+

+**/

+BOOLEAN

+EFIAPI

+CompareGuid (

+  IN CONST GUID  *Guid1,

+  IN CONST GUID  *Guid2

+  )

+{

+  return (CompareMem(Guid1, Guid2, sizeof(GUID) == 0)) ? TRUE : FALSE;

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from

+  the lowest address to the highest address at 128-bit increments for the 128-bit

+  GUID value that matches Guid.  If a match is found, then a pointer to the matching

+  GUID in the target buffer is returned.  If no match is found, then NULL is returned.

+  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 128-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Number of bytes in Buffer to scan.

+  @param  Guid    Value to search for in the target buffer.

+

+  @return A pointer to the matching Guid in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h
new file mode 100755
index 0000000..10c741f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            Number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 16-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 32-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Count of 64-bit value to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length Number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer First memory buffer

+  @param  SourceBuffer      Second memory buffer

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @return 0                 All Length bytes of the two buffers are identical.

+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first

+                            mismatched byte in DestinationBuffer.

+

+**/

+INTN

+EFIAPI

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 8-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 16-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 32-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  Pointer to the target buffer to scan.

+  @param  Length  Count of 64-bit value to scan. Must be non-zero.

+  @param  Value   Value to search for in the target buffer.

+

+  @return Pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c
new file mode 100755
index 0000000..1c727b3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the matching 16-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a 16-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c
new file mode 100755
index 0000000..79ab60c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the matching 32-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a 32-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c
new file mode 100755
index 0000000..d11e50b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the matching 64-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a 64-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c
new file mode 100755
index 0000000..c6c6d5f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the matching 8-bit value

+  in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for an 8-bit value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);

+}

+

+/**

+  Scans a target buffer for a UINTN sized value, and returns a pointer to the matching

+  UINTN sized value in the target buffer.

+

+  This function searches the target buffer specified by Buffer and Length from the lowest

+  address to the highest address for a UINTN sized value that matches Value.  If a match is found,

+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,

+  then NULL is returned.  If Length is 0, then NULL is returned.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Buffer is not aligned on a UINTN boundary, then ASSERT().

+  If Length is not aligned on a UINTN boundary, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to scan.

+  @param  Length      Number of bytes in Buffer to scan.

+  @param  Value       Value to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem.c
new file mode 100755
index 0000000..5c30e9b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem.c
@@ -0,0 +1,53 @@
+/** @file

+  Implementation of the EfiSetMem routine. This function is broken

+  out into its own source file so that it can be excluded from a

+  build for a particular platform easily if an optimized version

+  is desired.

+

+  Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   Memory to set.

+  @param  Length   Number of bytes to set

+  @param  Value    Value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memset()

+  //

+  volatile UINT8                    *Pointer;

+

+  Pointer = (UINT8*)Buffer;

+  while (Length-- > 0) {

+    *(Pointer++) = Value;

+  }

+  return Buffer;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c
new file mode 100755
index 0000000..8129d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 16-bit value specified by

+  Value, and returns Buffer. Value is repeated every 16-bits in for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem16 (

+  OUT VOID   *Buffer,

+  IN UINTN   Length,

+  IN UINT16  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c
new file mode 100755
index 0000000..b57ba40
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 32-bit value specified by

+  Value, and returns Buffer. Value is repeated every 32-bits in for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem32 (

+  OUT VOID   *Buffer,

+  IN UINTN   Length,

+  IN UINT32  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c
new file mode 100755
index 0000000..f979580
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the 64-bit value specified by

+  Value, and returns Buffer. Value is repeated every 64-bits in for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem64 (

+  OUT VOID   *Buffer,

+  IN UINTN   Length,

+  IN UINT64  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c
new file mode 100755
index 0000000..9240c89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a byte value, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with Value, and returns Buffer.

+

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer    Memory to set.

+  @param  Length    Number of bytes to set.

+  @param  Value     Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMem (

+  OUT VOID  *Buffer,

+  IN UINTN  Length,

+  IN UINT8  Value

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, Value);

+}

+

+/**

+  Fills a target buffer with a value that is size UINTN, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the UINTN sized value specified by

+  Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length

+  bytes of Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+  If Buffer is not aligned on a UINTN boundary, then ASSERT().

+  If Length is not aligned on a UINTN boundary, then ASSERT().

+

+  @param  Buffer  Pointer to the target buffer to fill.

+  @param  Length  Number of bytes in Buffer to fill.

+  @param  Value   Value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+SetMemN (

+  OUT VOID  *Buffer,

+  IN UINTN  Length,

+  IN UINTN  Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ZeroMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ZeroMemWrapper.c
new file mode 100755
index 0000000..d6c6279
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"

+

+/**

+  Fills a target buffer with zeros, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with zeros, and returns Buffer.

+

+  If Length > 0 and Buffer is NULL, then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  @param  Buffer      Pointer to the target buffer to fill with zeros.

+  @param  Length      Number of bytes in Buffer to fill with zeros.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+ZeroMem (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
new file mode 100644
index 0000000..e094413
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
@@ -0,0 +1,349 @@
+/** @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.

+*

+**/

+#include <Library/ArmGicLib.h>

+#include <Ppi/ArmMpCoreInfo.h>

+#include <Library/IoLib.h>

+

+#include "BdsInternal.h"

+#include "BdsLinuxLoader.h"

+

+/*

+  Linux kernel booting: Look at the doc in the Kernel source :

+    Documentation/arm64/booting.txt

+  The kernel image must be placed at the start of the memory to be used by the

+  kernel (2MB aligned) + 0x80000.

+

+  The Device tree blob is expected to be under 2MB and be within the first 512MB

+  of kernel memory and be 2MB aligned.

+

+  A Flattened Device Tree (FDT) used to boot linux needs to be updated before

+  the kernel is started. It needs to indicate how secondary cores are brought up

+  and where they are waiting before loading Linux. The FDT also needs to hold

+  the correct kernel command line and filesystem RAM-disk information.

+  At the moment we do not fully support generating this FDT information at

+  runtime. A prepared FDT should be provided at boot. FDT is the only supported

+  method for booting the AArch64 Linux kernel.

+

+  Linux does not use any runtime services at this time, so we can let it

+  overwrite UEFI.

+*/

+

+

+#define LINUX_ALIGN_VAL       (0x080000) // 2MB + 0x80000 mask

+#define LINUX_ALIGN_MASK      (0x1FFFFF) // Bottom 21bits

+#define ALIGN_2MB(addr)       ALIGN_POINTER(addr , (2*1024*1024))

+

+/* ARM32 and AArch64 kernel handover differ.

+ * x0 is set to FDT base.

+ * x1-x3 are reserved for future use and should be set to zero.

+ */

+typedef VOID (*LINUX_KERNEL64)(UINTN ParametersBase, UINTN Reserved0,

+                               UINTN Reserved1, UINTN Reserved2);

+

+/* These externs are used to relocate some ASM code into Linux memory. */

+extern VOID  *SecondariesPenStart;

+extern VOID  *SecondariesPenEnd;

+extern UINTN *AsmMailboxbase;

+

+

+STATIC

+EFI_STATUS

+PreparePlatformHardware (

+  VOID

+  )

+{

+  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.

+

+  // Clean before Disable else the Stack gets corrupted with old data.

+  ArmCleanDataCache ();

+  ArmDisableDataCache ();

+  // Invalidate all the entries that might have snuck in.

+  ArmInvalidateDataCache ();

+

+  // Disable and invalidate the instruction cache

+  ArmDisableInstructionCache ();

+  ArmInvalidateInstructionCache ();

+

+  // Turn off MMU

+  ArmDisableMmu();

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+StartLinux (

+  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,

+  IN  UINTN                 LinuxImageSize,

+  IN  EFI_PHYSICAL_ADDRESS  FdtBlobBase,

+  IN  UINTN                 FdtBlobSize

+  )

+{

+  EFI_STATUS            Status;

+  LINUX_KERNEL64        LinuxKernel = (LINUX_KERNEL64)LinuxImage;

+

+  // Send msg to secondary cores to go to the kernel pen.

+  ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));

+

+  // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on

+  // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.

+  Status = ShutdownUefiBootServices ();

+  if(EFI_ERROR(Status)) {

+    DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));

+    goto Exit;

+  }

+

+  // Check if the Linux Image is a uImage

+  if (*(UINTN*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {

+    // Assume the Image Entry Point is just after the uImage header (64-byte size)

+    LinuxKernel = (LINUX_KERNEL64)((UINTN)LinuxKernel + 64);

+    LinuxImageSize -= 64;

+  }

+

+  //

+  // Switch off interrupts, caches, mmu, etc

+  //

+  Status = PreparePlatformHardware ();

+  ASSERT_EFI_ERROR(Status);

+

+  // Register and print out performance information

+  PERF_END (NULL, "BDS", NULL, 0);

+  if (PerformanceMeasurementEnabled ()) {

+    PrintPerformance ();

+  }

+

+  //

+  // Start the Linux Kernel

+  //

+

+  // x1-x3 are reserved (set to zero) for future use.

+  LinuxKernel ((UINTN)FdtBlobBase, 0, 0, 0);

+

+  // Kernel should never exit

+  // After Life services are not provided

+  ASSERT(FALSE);

+

+Exit:

+  // Only be here if we fail to start Linux

+  Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);

+

+  // Free Runtimee Memory (kernel and FDT)

+  return Status;

+}

+

+

+/**

+  Start a Linux kernel from a Device Path

+

+  @param  LinuxKernel           Device Path to the Linux Kernel

+  @param  Parameters            Linux kernel agruments

+  @param  Fdt                   Device Path to the Flat Device Tree

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsBootLinuxAtag (

+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,

+  IN  CONST CHAR8*              Arguments

+  )

+{

+  // NOTE : AArch64 Linux kernel does not support ATAG, FDT only.

+  ASSERT(0);

+

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Start a Linux kernel from a Device Path

+

+  @param  LinuxKernel           Device Path to the Linux Kernel

+  @param  Parameters            Linux kernel agruments

+  @param  Fdt                   Device Path to the Flat Device Tree

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsBootLinuxFdt (

+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,

+  IN  CONST CHAR8*              Arguments,

+  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath

+  )

+{

+  EFI_STATUS            Status;

+  EFI_STATUS            PenBaseStatus;

+  UINTN                 LinuxImageSize;

+  UINTN                 InitrdImageSize;

+  UINTN                 InitrdImageBaseSize;

+  UINTN                 FdtBlobSize;

+  EFI_PHYSICAL_ADDRESS  FdtBlobBase;

+  EFI_PHYSICAL_ADDRESS  LinuxImage;

+  EFI_PHYSICAL_ADDRESS  InitrdImage;

+  EFI_PHYSICAL_ADDRESS  InitrdImageBase;

+  ARM_PROCESSOR_TABLE   *ArmProcessorTable;

+  ARM_CORE_INFO         *ArmCoreInfoTable;

+  UINTN                 Index;

+  EFI_PHYSICAL_ADDRESS  PenBase;

+  UINTN                 PenSize;

+  UINTN                 MailBoxBase;

+

+  PenBaseStatus = EFI_UNSUPPORTED;

+  PenSize = 0;

+  InitrdImage = 0;

+  InitrdImageSize = 0;

+  InitrdImageBase = 0;

+  InitrdImageBaseSize = 0;

+

+  PERF_START (NULL, "BDS", NULL, 0);

+

+  //

+  // Load the Linux kernel from a device path

+  //

+

+  // Try to put the kernel at the start of RAM so as to give it access to all memory.

+  // If that fails fall back to try loading it within LINUX_KERNEL_MAX_OFFSET of memory start.

+  LinuxImage = PcdGet64 (PcdSystemMemoryBase) + 0x80000;

+  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateAddress, &LinuxImage, &LinuxImageSize);

+  if (EFI_ERROR(Status)) {

+    // Try again but give the loader more freedom of where to put the image.

+    LinuxImage = LINUX_KERNEL_MAX_OFFSET;

+    Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);

+    if (EFI_ERROR(Status)) {

+      Print (L"ERROR: Did not find Linux kernel (%r).\n", Status);

+      return Status;

+    }

+  }

+  // Adjust the kernel location slightly if required. The kernel needs to be placed at start

+  //  of memory (2MB aligned) + 0x80000.

+  if ((LinuxImage & LINUX_ALIGN_MASK) != LINUX_ALIGN_VAL) {

+    LinuxImage = (EFI_PHYSICAL_ADDRESS)CopyMem (ALIGN_2MB(LinuxImage) + 0x80000, (VOID*)(UINTN)LinuxImage, LinuxImageSize);

+  }

+

+  if (InitrdDevicePath) {

+    InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;

+    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);

+    if (Status == EFI_OUT_OF_RESOURCES) {

+      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);

+    }

+    if (EFI_ERROR (Status)) {

+      Print (L"ERROR: Did not find initrd image (%r).\n", Status);

+      goto EXIT_FREE_LINUX;

+    }

+

+    // Check if the initrd is a uInitrd

+    if (*(UINTN*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {

+      // Skip the 64-byte image header

+      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);

+      InitrdImageSize = InitrdImageBaseSize - 64;

+    } else {

+      InitrdImage = InitrdImageBase;

+      InitrdImageSize = InitrdImageBaseSize;

+    }

+  }

+

+  // Load the FDT binary from a device path.

+  // The FDT will be reloaded later to a more appropriate location for the Linux kernel.

+  FdtBlobBase = LINUX_KERNEL_MAX_OFFSET;

+  Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize);

+  if (EFI_ERROR(Status)) {

+    Print (L"ERROR: Did not find Device Tree blob (%r).\n", Status);

+    goto EXIT_FREE_INITRD;

+  }

+

+  //

+  // Install secondary core pens if the Power State Coordination Interface is not supported

+  //

+  if (FeaturePcdGet (PcdArmLinuxSpinTable)) {

+    // Place Pen at the start of Linux memory. We can then tell Linux to not use this bit of memory

+    PenBase  = LinuxImage - 0x80000;

+    PenSize  = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart;

+

+    // Reserve the memory as RuntimeServices

+    PenBaseStatus = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode, EFI_SIZE_TO_PAGES (PenSize), &PenBase);

+    if (EFI_ERROR (PenBaseStatus)) {

+      Print (L"Warning: Failed to reserve the memory required for the secondary cores at 0x%lX, Status = %r\n", PenBase, PenBaseStatus);

+      // Even if there is a risk of memory corruption we carry on

+    }

+

+    // Put mailboxes below the pen code so we know where they are relative to code.

+    MailBoxBase = (UINTN)PenBase + ((UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart);

+    // Make sure this is 8 byte aligned.

+    if (MailBoxBase % sizeof(MailBoxBase) != 0) {

+      MailBoxBase += sizeof(MailBoxBase) - MailBoxBase % sizeof(MailBoxBase);

+    }

+

+    CopyMem ( (VOID*)(PenBase), (VOID*)&SecondariesPenStart, PenSize);

+

+    // Update the MailboxBase variable used in the pen code

+    *(UINTN*)(PenBase + ((UINTN)&AsmMailboxbase - (UINTN)&SecondariesPenStart)) = MailBoxBase;

+

+    for (Index=0; Index < gST->NumberOfTableEntries; Index++) {

+      // Check for correct GUID type

+      if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {

+        UINTN i;

+

+        // Get them under our control. Move from depending on 32bit reg(sys_flags) and SWI

+        // to 64 bit addr and WFE

+        ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable;

+        ArmCoreInfoTable = ArmProcessorTable->ArmCpus;

+

+        for (i = 0; i < ArmProcessorTable->NumberOfEntries; i++ ) {

+          // This goes into the SYSFLAGS register for the VE platform. We only have one 32bit reg to use

+          MmioWrite32(ArmCoreInfoTable[i].MailboxSetAddress, (UINTN)PenBase);

+

+          // So FDT can set the mailboxes correctly with the parser. These are 64bit Memory locations.

+          ArmCoreInfoTable[i].MailboxSetAddress = (UINTN)MailBoxBase + i*sizeof(MailBoxBase);

+

+          // Clear the mailboxes for the respective cores

+          *((UINTN*)(ArmCoreInfoTable[i].MailboxSetAddress)) = 0x0;

+        }

+      }

+    }

+    // Flush caches to make sure our pen gets to mem before we free the cores.

+    ArmCleanDataCache();

+  }

+

+  // By setting address=0 we leave the memory allocation to the function

+  Status = PrepareFdt (Arguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);

+  if (EFI_ERROR(Status)) {

+    Print(L"ERROR: Can not load Linux kernel with Device Tree. Status=0x%X\n", Status);

+    goto EXIT_FREE_FDT;

+  }

+

+  return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize);

+

+EXIT_FREE_FDT:

+  if (!EFI_ERROR (PenBaseStatus)) {

+    gBS->FreePages (PenBase, EFI_SIZE_TO_PAGES (PenSize));

+  }

+

+  gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));

+

+EXIT_FREE_INITRD:

+  if (InitrdDevicePath) {

+    gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));

+  }

+

+EXIT_FREE_LINUX:

+  gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S
new file mode 100644
index 0000000..525c128
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S
@@ -0,0 +1,58 @@
+//

+//  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.

+//

+//

+

+

+/* Secondary core pens for AArch64 Linux booting.

+

+   This code it placed in Linux kernel memory and marked reserved. UEFI ensures

+   that the secondary cores get to this pen and the kernel can then start the

+   cores from here.

+   NOTE: This code must be self-contained.

+*/

+

+#include <Library/ArmLib.h>

+

+.text

+.align 3

+

+GCC_ASM_EXPORT(SecondariesPenStart)

+ASM_GLOBAL SecondariesPenEnd

+

+ASM_PFX(SecondariesPenStart):

+   // Registers x0-x3 are reserved for future use and should be set to zero.

+   mov x0, xzr

+   mov x1, xzr

+   mov x2, xzr

+   mov x3, xzr

+

+   // Get core position. Taken from ArmPlatformGetCorePosition().

+   // Assumes max 4 cores per cluster.

+   mrs x4, mpidr_el1             // Get MPCore register.

+   and x5, x4, #ARM_CORE_MASK    // Get core number.

+   and x4, x4, #ARM_CLUSTER_MASK // Get cluster number.

+   add x4, x5, x4, LSR #6        // Add scaled cluster number to core number.

+   lsl x4, x4, 3            // Get mailbox offset for this core.

+   ldr x5, AsmMailboxbase   // Get mailbox addr relative to pc (36 bytes ahead).

+   add x4, x4, x5           // Add core mailbox offset to base of mailbox.

+1: ldr x5, [x4]             // Load value from mailbox.

+   cmp xzr, x5              // Has the mailbox been set?

+   b.ne 2f                  // If so break out of loop.

+   wfe                      // If not, wait a bit.

+   b 1b                     // Wait over, check if mailbox set again.

+2: br x5                    // Jump to mailbox value.

+

+.align 3 // Make sure the variable below is 8 byte aligned.

+                .global     AsmMailboxbase

+AsmMailboxbase: .xword      0xdeaddeadbeefbeef

+

+SecondariesPenEnd:

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c
new file mode 100644
index 0000000..33c2798
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c
@@ -0,0 +1,173 @@
+/** @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.

+*

+**/

+

+#include "BdsInternal.h"

+#include "BdsLinuxLoader.h"

+

+// Point to the current ATAG

+STATIC LINUX_ATAG *mLinuxKernelCurrentAtag;

+

+STATIC

+VOID

+SetupCoreTag (

+  IN UINT32 PageSize

+  )

+{

+  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_CORE);

+  mLinuxKernelCurrentAtag->header.type = ATAG_CORE;

+

+  mLinuxKernelCurrentAtag->body.core_tag.flags    = 1;            /* ensure read-only */

+  mLinuxKernelCurrentAtag->body.core_tag.pagesize = PageSize;     /* systems PageSize (4k) */

+  mLinuxKernelCurrentAtag->body.core_tag.rootdev  = 0;            /* zero root device (typically overridden from kernel command line )*/

+

+  // move pointer to next tag

+  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);

+}

+

+STATIC

+VOID

+SetupMemTag (

+  IN UINTN StartAddress,

+  IN UINT32 Size

+  )

+{

+  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_MEM);

+  mLinuxKernelCurrentAtag->header.type = ATAG_MEM;

+

+  mLinuxKernelCurrentAtag->body.mem_tag.start = StartAddress;    /* Start of memory chunk for AtagMem */

+  mLinuxKernelCurrentAtag->body.mem_tag.size  = Size;             /* Size of memory chunk for AtagMem */

+

+  // move pointer to next tag

+  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);

+}

+

+STATIC

+VOID

+SetupCmdlineTag (

+  IN CONST CHAR8 *CmdLine

+  )

+{

+  UINT32 LineLength;

+

+  // Increment the line length by 1 to account for the null string terminator character

+  LineLength = AsciiStrLen(CmdLine) + 1;

+

+  /* Check for NULL strings.

+   * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.

+   * Remember, you have at least one null string terminator character.

+   */

+  if(LineLength > 1) {

+    mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2;

+    mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE;

+

+    /* place CommandLine into tag */

+    AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine);

+

+    // move pointer to next tag

+    mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);

+  }

+}

+

+STATIC

+VOID

+SetupInitrdTag (

+  IN UINT32 InitrdImage,

+  IN UINT32 InitrdImageSize

+  )

+{

+  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2);

+  mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2;

+

+  mLinuxKernelCurrentAtag->body.initrd2_tag.start = InitrdImage;

+  mLinuxKernelCurrentAtag->body.initrd2_tag.size = InitrdImageSize;

+

+  // Move pointer to next tag

+  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);

+}

+STATIC

+VOID

+SetupEndTag (

+  VOID

+  )

+{

+  // Empty tag ends list; this has zero length and no body

+  mLinuxKernelCurrentAtag->header.type = ATAG_NONE;

+  mLinuxKernelCurrentAtag->header.size = 0;

+

+  /* We can not calculate the next address by using the standard macro:

+   * Params = next_tag_address(Params);

+   * because it relies on the header.size, which here it is 0 (zero).

+   * The easiest way is to add the sizeof(mLinuxKernelCurrentAtag->header).

+   */

+  mLinuxKernelCurrentAtag = (LINUX_ATAG*)((UINT32)mLinuxKernelCurrentAtag + sizeof(mLinuxKernelCurrentAtag->header));

+}

+

+EFI_STATUS

+PrepareAtagList (

+  IN  CONST CHAR8*          CommandLineString,

+  IN  EFI_PHYSICAL_ADDRESS  InitrdImage,

+  IN  UINTN                 InitrdImageSize,

+  OUT EFI_PHYSICAL_ADDRESS  *AtagBase,

+  OUT UINT32                *AtagSize

+  )

+{

+  EFI_STATUS                  Status;

+  LIST_ENTRY                  *ResourceLink;

+  LIST_ENTRY                  ResourceList;

+  EFI_PHYSICAL_ADDRESS        AtagStartAddress;

+  BDS_SYSTEM_MEMORY_RESOURCE  *Resource;

+

+  AtagStartAddress = LINUX_ATAG_MAX_OFFSET;

+  Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);

+  if (EFI_ERROR(Status)) {

+    DEBUG ((EFI_D_WARN, "Warning: Failed to allocate Atag at 0x%lX (%r). The Atag will be allocated somewhere else in System Memory.\n", AtagStartAddress, Status));

+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);

+    ASSERT_EFI_ERROR(Status);

+  }

+

+  // Ready to setup the atag list

+  mLinuxKernelCurrentAtag = (LINUX_ATAG*)(UINTN)AtagStartAddress;

+

+  // Standard core tag 4k PageSize

+  SetupCoreTag( (UINT32)SIZE_4KB );

+

+  // Physical memory setup

+  GetSystemMemoryResources (&ResourceList);

+  ResourceLink = ResourceList.ForwardLink;

+  while (ResourceLink != NULL && ResourceLink != &ResourceList) {

+    Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceLink;

+    DEBUG((EFI_D_INFO,"- [0x%08X,0x%08X]\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->PhysicalStart+(UINT32)Resource->ResourceLength));

+    SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );

+    ResourceLink = ResourceLink->ForwardLink;

+  }

+

+  // CommandLine setting root device

+  if (CommandLineString) {

+    SetupCmdlineTag (CommandLineString);

+  }

+

+  if (InitrdImageSize > 0 && InitrdImage != 0) {

+    SetupInitrdTag ((UINT32)InitrdImage, (UINT32)InitrdImageSize);

+  }

+

+  // End of tags

+  SetupEndTag();

+

+  // Calculate atag list size

+  *AtagBase = AtagStartAddress;

+  *AtagSize = (UINT32)mLinuxKernelCurrentAtag - (UINT32)AtagStartAddress + 1;

+

+  return EFI_SUCCESS;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c
new file mode 100644
index 0000000..42f301d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c
@@ -0,0 +1,315 @@
+/** @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.

+*

+**/

+

+#include "BdsInternal.h"

+#include "BdsLinuxLoader.h"

+

+#define ALIGN32_BELOW(addr)   ALIGN_POINTER(addr - 32,32)

+

+#define IS_ADDRESS_IN_REGION(RegionStart, RegionSize, Address) \

+    (((UINTN)(RegionStart) <= (UINTN)(Address)) && ((UINTN)(Address) <= ((UINTN)(RegionStart) + (UINTN)(RegionSize))))

+

+STATIC

+EFI_STATUS

+PreparePlatformHardware (

+  VOID

+  )

+{

+  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.

+

+  // Clean before Disable else the Stack gets corrupted with old data.

+  ArmCleanDataCache ();

+  ArmDisableDataCache ();

+  // Invalidate all the entries that might have snuck in.

+  ArmInvalidateDataCache ();

+

+  // Invalidate and disable the Instruction cache

+  ArmDisableInstructionCache ();

+  ArmInvalidateInstructionCache ();

+

+  // Turn off MMU

+  ArmDisableMmu();

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+StartLinux (

+  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,

+  IN  UINTN                 LinuxImageSize,

+  IN  EFI_PHYSICAL_ADDRESS  KernelParamsAddress,

+  IN  UINTN                 KernelParamsSize,

+  IN  UINT32                MachineType

+  )

+{

+  EFI_STATUS            Status;

+  LINUX_KERNEL          LinuxKernel;

+

+  // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on

+  // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.

+  Status = ShutdownUefiBootServices ();

+  if(EFI_ERROR(Status)) {

+    DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));

+    goto Exit;

+  }

+

+  // Move the kernel parameters to any address inside the first 1MB.

+  // This is necessary because the ARM Linux kernel requires

+  // the FTD / ATAG List to reside entirely inside the first 1MB of

+  // physical memory.

+  //Note: There is no requirement on the alignment

+  if (MachineType != ARM_FDT_MACHINE_TYPE) {

+    if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {

+      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);

+    }

+  } else {

+    if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {

+      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);

+    }

+  }

+

+  if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {

+    //Note: There is no requirement on the alignment

+    LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);

+  } else {

+    LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;

+  }

+

+  // Check if the Linux Image is a uImage

+  if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {

+    // Assume the Image Entry Point is just after the uImage header (64-byte size)

+    LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);

+    LinuxImageSize -= 64;

+  }

+

+  // Check there is no overlapping between kernel and its parameters

+  // We can only assert because it is too late to fallback to UEFI (ExitBootServices has been called).

+  ASSERT (!IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress) &&

+          !IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress + KernelParamsSize));

+

+  //

+  // Switch off interrupts, caches, mmu, etc

+  //

+  Status = PreparePlatformHardware ();

+  ASSERT_EFI_ERROR(Status);

+

+  // Register and print out performance information

+  PERF_END (NULL, "BDS", NULL, 0);

+  if (PerformanceMeasurementEnabled ()) {

+    PrintPerformance ();

+  }

+

+  //

+  // Start the Linux Kernel

+  //

+

+  // Outside BootServices, so can't use Print();

+  DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));

+

+  // Jump to kernel with register set

+  LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);

+

+  // Kernel should never exit

+  // After Life services are not provided

+  ASSERT(FALSE);

+

+Exit:

+  // Only be here if we fail to start Linux

+  Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);

+

+  // Free Runtimee Memory (kernel and FDT)

+  return Status;

+}

+

+/**

+  Start a Linux kernel from a Device Path

+

+  @param  LinuxKernel           Device Path to the Linux Kernel

+  @param  Parameters            Linux kernel arguments

+  @param  Fdt                   Device Path to the Flat Device Tree

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsBootLinuxAtag (

+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,

+  IN  CONST CHAR8*              CommandLineArguments

+  )

+{

+  EFI_STATUS            Status;

+  UINT32                LinuxImageSize;

+  UINT32                InitrdImageBaseSize = 0;

+  UINT32                InitrdImageSize = 0;

+  UINT32                AtagSize;

+  EFI_PHYSICAL_ADDRESS  AtagBase;

+  EFI_PHYSICAL_ADDRESS  LinuxImage;

+  EFI_PHYSICAL_ADDRESS  InitrdImageBase = 0;

+  EFI_PHYSICAL_ADDRESS  InitrdImage = 0;

+

+  PERF_START (NULL, "BDS", NULL, 0);

+

+  // Load the Linux kernel from a device path

+  LinuxImage = LINUX_KERNEL_MAX_OFFSET;

+  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);

+  if (EFI_ERROR(Status)) {

+    Print (L"ERROR: Did not find Linux kernel.\n");

+    return Status;

+  }

+

+  if (InitrdDevicePath) {

+    // Load the initrd near to the Linux kernel

+    InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;

+    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);

+    if (Status == EFI_OUT_OF_RESOURCES) {

+      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);

+    }

+    if (EFI_ERROR(Status)) {

+      Print (L"ERROR: Did not find initrd image.\n");

+      goto EXIT_FREE_LINUX;

+    }

+

+    // Check if the initrd is a uInitrd

+    if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {

+      // Skip the 64-byte image header

+      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);

+      InitrdImageSize = InitrdImageBaseSize - 64;

+    } else {

+      InitrdImage = InitrdImageBase;

+      InitrdImageSize = InitrdImageBaseSize;

+    }

+  }

+

+  //

+  // Setup the Linux Kernel Parameters

+  //

+

+  // By setting address=0 we leave the memory allocation to the function

+  Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize);

+  if (EFI_ERROR(Status)) {

+    Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);

+    goto EXIT_FREE_INITRD;

+  }

+

+  return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));

+

+EXIT_FREE_INITRD:

+  if (InitrdDevicePath) {

+    gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));

+  }

+

+EXIT_FREE_LINUX:

+  gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));

+

+  return Status;

+}

+

+/**

+  Start a Linux kernel from a Device Path

+

+  @param  LinuxKernel           Device Path to the Linux Kernel

+  @param  Parameters            Linux kernel arguments

+  @param  Fdt                   Device Path to the Flat Device Tree

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsBootLinuxFdt (

+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,

+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,

+  IN  CONST CHAR8*              CommandLineArguments,

+  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath

+  )

+{

+  EFI_STATUS            Status;

+  UINT32                LinuxImageSize;

+  UINT32                InitrdImageBaseSize = 0;

+  UINT32                InitrdImageSize = 0;

+  UINT32                FdtBlobSize;

+  EFI_PHYSICAL_ADDRESS  FdtBlobBase;

+  EFI_PHYSICAL_ADDRESS  LinuxImage;

+  EFI_PHYSICAL_ADDRESS  InitrdImageBase = 0;

+  EFI_PHYSICAL_ADDRESS  InitrdImage = 0;

+

+  PERF_START (NULL, "BDS", NULL, 0);

+

+  // Load the Linux kernel from a device path

+  LinuxImage = LINUX_KERNEL_MAX_OFFSET;

+  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);

+  if (EFI_ERROR(Status)) {

+    Print (L"ERROR: Did not find Linux kernel.\n");

+    return Status;

+  }

+

+  if (InitrdDevicePath) {

+    InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;

+    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);

+    if (Status == EFI_OUT_OF_RESOURCES) {

+      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);

+    }

+    if (EFI_ERROR(Status)) {

+      Print (L"ERROR: Did not find initrd image.\n");

+      goto EXIT_FREE_LINUX;

+    }

+

+    // Check if the initrd is a uInitrd

+    if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {

+      // Skip the 64-byte image header

+      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);

+      InitrdImageSize = InitrdImageBaseSize - 64;

+    } else {

+      InitrdImage = InitrdImageBase;

+      InitrdImageSize = InitrdImageBaseSize;

+    }

+  }

+

+  // Load the FDT binary from a device path. The FDT will be reloaded later to a more appropriate location for the Linux kernel.

+  FdtBlobBase = 0;

+  Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);

+  if (EFI_ERROR(Status)) {

+    Print (L"ERROR: Did not find Device Tree blob.\n");

+    goto EXIT_FREE_INITRD;

+  }

+

+  // Update the Fdt with the Initrd information. The FDT will increase in size.

+  // By setting address=0 we leave the memory allocation to the function

+  Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);

+  if (EFI_ERROR(Status)) {

+    Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);

+    goto EXIT_FREE_FDT;

+  }

+

+  return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);

+

+EXIT_FREE_FDT:

+  gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));

+

+EXIT_FREE_INITRD:

+  if (InitrdDevicePath) {

+    gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));

+  }

+

+EXIT_FREE_LINUX:

+  gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));

+

+  return Status;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsAppLoader.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsAppLoader.c
new file mode 100644
index 0000000..2b88bf1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsAppLoader.c
@@ -0,0 +1,144 @@
+/** @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.

+*

+**/

+

+#include "BdsInternal.h"

+

+//#include <Library/DxeServicesLib.h>

+

+STATIC

+EFI_STATUS

+BdsLoadFileFromFirmwareVolume (

+  IN  EFI_HANDLE      FvHandle,

+  IN  CHAR16    *FilePath,

+  IN  EFI_FV_FILETYPE FileTypeFilter,

+  OUT EFI_DEVICE_PATH     **EfiAppDevicePath

+  )

+{

+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;

+  VOID                          *Key;

+  EFI_STATUS                    Status, FileStatus;

+  EFI_GUID                      NameGuid;

+  EFI_FV_FILETYPE               FileType;

+  EFI_FV_FILE_ATTRIBUTES        Attributes;

+  UINTN                         Size;

+  UINTN                         UiStringLen;

+  CHAR16                        *UiSection;

+  UINT32                        Authentication;

+  EFI_DEVICE_PATH               *FvDevicePath;

+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;

+

+  Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  // Length of FilePath

+  UiStringLen = StrLen (FilePath);

+

+  // Allocate Key

+  Key = AllocatePool (FvProtocol->KeySize);

+  ASSERT (Key != NULL);

+  ZeroMem (Key, FvProtocol->KeySize);

+

+  do {

+    // Search in all files

+    FileType = FileTypeFilter;

+

+    Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);

+    if (!EFI_ERROR (Status)) {

+      UiSection = NULL;

+      FileStatus = FvProtocol->ReadSection (

+                    FvProtocol,

+                    &NameGuid,

+                    EFI_SECTION_USER_INTERFACE,

+                    0,

+                    (VOID **)&UiSection,

+                    &Size,

+                    &Authentication

+                    );

+      if (!EFI_ERROR (FileStatus)) {

+        if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {

+          //

+          // We found a UiString match.

+          //

+          Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);

+

+          // Generate the Device Path for the file

+          //DevicePath = DuplicateDevicePath(FvDevicePath);

+          EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);

+          *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);

+

+          FreePool (Key);

+          FreePool (UiSection);

+          return FileStatus;

+        }

+        FreePool (UiSection);

+      }

+    }

+  } while (!EFI_ERROR (Status));

+

+  FreePool(Key);

+  return Status;

+}

+

+/**

+  Start an EFI Application from any Firmware Volume

+

+  @param  EfiApp                EFI Application Name

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsLoadApplication (

+  IN EFI_HANDLE                  ParentImageHandle,

+  IN CHAR16*                     EfiApp,

+  IN UINTN                       LoadOptionsSize,

+  IN VOID*                       LoadOptions

+  )

+{

+  EFI_STATUS                      Status;

+  UINTN                           NoHandles, HandleIndex;

+  EFI_HANDLE                      *Handles;

+  EFI_DEVICE_PATH                 *EfiAppDevicePath;

+

+  // Need to connect every drivers to ensure no dependencies are missing for the application

+  Status = BdsConnectAllDrivers();

+  if (EFI_ERROR(Status)) {

+    DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));

+    return Status;

+  }

+

+  // Search the application in any Firmware Volume

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);

+  if (EFI_ERROR (Status) || (NoHandles == 0)) {

+    DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));

+    return Status;

+  }

+

+  // Search in all Firmware Volume for the EFI Application

+  for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {

+    EfiAppDevicePath = NULL;

+    Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);

+    if (!EFI_ERROR (Status)) {

+      // Start the application

+      Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);

+      return Status;

+    }

+  }

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsFilePath.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsFilePath.c
new file mode 100644
index 0000000..924c61e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsFilePath.c
@@ -0,0 +1,1418 @@
+/** @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.

+*

+**/

+

+#include "BdsInternal.h"

+

+#include <Library/NetLib.h>

+

+#include <Protocol/Bds.h>

+#include <Protocol/UsbIo.h>

+#include <Protocol/DiskIo.h>

+#include <Protocol/LoadedImage.h>

+#include <Protocol/SimpleNetwork.h>

+#include <Protocol/Dhcp4.h>

+#include <Protocol/Mtftp4.h>

+

+

+#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))

+

+/* Type and defines to set up the DHCP4 options */

+

+typedef struct {

+  EFI_DHCP4_PACKET_OPTION Head;

+  UINT8                   Route;

+} DHCP4_OPTION;

+

+#define DHCP_TAG_PARA_LIST  55

+#define DHCP_TAG_NETMASK     1

+#define DHCP_TAG_ROUTER      3

+

+/*

+   Constant strings and define related to the message indicating the amount of

+   progress in the dowloading of a TFTP file.

+*/

+

+// Frame for the progression slider

+STATIC CONST CHAR16 mTftpProgressFrame[] = L"[                                        ]";

+

+// Number of steps in the progression slider

+#define TFTP_PROGRESS_SLIDER_STEPS  ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)

+

+// Size in number of characters plus one (final zero) of the message to

+// indicate the progress of a tftp download. The format is "[(progress slider:

+// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There

+// are thus the number of characters in mTftpProgressFrame[] plus 11 characters

+// (2 // spaces, "Kb" and seven characters for the number of KBytes).

+#define TFTP_PROGRESS_MESSAGE_SIZE  ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12)

+

+// String to delete the tftp progress message to be able to update it :

+// (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'

+STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";

+

+

+// Extract the FilePath from the Device Path

+CHAR16*

+BdsExtractFilePathFromDevicePath (

+  IN  CONST CHAR16    *StrDevicePath,

+  IN  UINTN           NumberDevicePathNode

+  )

+{

+  UINTN       Node;

+  CHAR16      *Str;

+

+  Str = (CHAR16*)StrDevicePath;

+  Node = 0;

+  while ((Str != NULL) && (*Str != L'\0') && (Node < NumberDevicePathNode)) {

+    if ((*Str == L'/') || (*Str == L'\\')) {

+        Node++;

+    }

+    Str++;

+  }

+

+  if (*Str == L'\0') {

+    return NULL;

+  } else {

+    return Str;

+  }

+}

+

+BOOLEAN

+BdsIsRemovableUsb (

+  IN  EFI_DEVICE_PATH*  DevicePath

+  )

+{

+  return ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&

+          ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) ||

+           (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)));

+}

+

+EFI_STATUS

+BdsGetDeviceUsb (

+  IN  EFI_DEVICE_PATH*  RemovableDevicePath,

+  OUT EFI_HANDLE*       DeviceHandle,

+  OUT EFI_DEVICE_PATH** NewDevicePath

+  )

+{

+  EFI_STATUS                    Status;

+  UINTN                         Index;

+  UINTN                         UsbIoHandleCount;

+  EFI_HANDLE                    *UsbIoBuffer;

+  EFI_DEVICE_PATH*              UsbIoDevicePath;

+  EFI_DEVICE_PATH*              TmpDevicePath;

+  USB_WWID_DEVICE_PATH*         WwidDevicePath1;

+  USB_WWID_DEVICE_PATH*         WwidDevicePath2;

+  USB_CLASS_DEVICE_PATH*        UsbClassDevicePath1;

+  USB_CLASS_DEVICE_PATH*        UsbClassDevicePath2;

+

+  // Get all the UsbIo handles

+  UsbIoHandleCount = 0;

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);

+  if (EFI_ERROR (Status) || (UsbIoHandleCount == 0)) {

+    return Status;

+  }

+

+  // Check if one of the handles matches the USB description

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

+    Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &UsbIoDevicePath);

+    if (!EFI_ERROR (Status)) {

+      TmpDevicePath = UsbIoDevicePath;

+      while (!IsDevicePathEnd (TmpDevicePath)) {

+        // Check if the Device Path node is a USB Removable device Path node

+        if (BdsIsRemovableUsb (TmpDevicePath)) {

+          if (TmpDevicePath->SubType == MSG_USB_WWID_DP) {

+            WwidDevicePath1 = (USB_WWID_DEVICE_PATH*)RemovableDevicePath;

+            WwidDevicePath2 = (USB_WWID_DEVICE_PATH*)TmpDevicePath;

+            if ((WwidDevicePath1->VendorId == WwidDevicePath2->VendorId) &&

+                (WwidDevicePath1->ProductId == WwidDevicePath2->ProductId) &&

+                (CompareMem (WwidDevicePath1+1, WwidDevicePath2+1, DevicePathNodeLength(WwidDevicePath1)-sizeof (USB_WWID_DEVICE_PATH)) == 0))

+            {

+              *DeviceHandle = UsbIoBuffer[Index];

+              // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path

+              *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));

+              return EFI_SUCCESS;

+            }

+          } else {

+            UsbClassDevicePath1 = (USB_CLASS_DEVICE_PATH*)RemovableDevicePath;

+            UsbClassDevicePath2 = (USB_CLASS_DEVICE_PATH*)TmpDevicePath;

+            if ((UsbClassDevicePath1->VendorId != 0xFFFF) && (UsbClassDevicePath1->VendorId == UsbClassDevicePath2->VendorId) &&

+                (UsbClassDevicePath1->ProductId != 0xFFFF) && (UsbClassDevicePath1->ProductId == UsbClassDevicePath2->ProductId) &&

+                (UsbClassDevicePath1->DeviceClass != 0xFF) && (UsbClassDevicePath1->DeviceClass == UsbClassDevicePath2->DeviceClass) &&

+                (UsbClassDevicePath1->DeviceSubClass != 0xFF) && (UsbClassDevicePath1->DeviceSubClass == UsbClassDevicePath2->DeviceSubClass) &&

+                (UsbClassDevicePath1->DeviceProtocol != 0xFF) && (UsbClassDevicePath1->DeviceProtocol == UsbClassDevicePath2->DeviceProtocol))

+            {

+              *DeviceHandle = UsbIoBuffer[Index];

+              // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path

+              *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));

+              return EFI_SUCCESS;

+            }

+          }

+        }

+        TmpDevicePath = NextDevicePathNode (TmpDevicePath);

+      }

+

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+BOOLEAN

+BdsIsRemovableHd (

+  IN  EFI_DEVICE_PATH*  DevicePath

+  )

+{

+  return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP);

+}

+

+EFI_STATUS

+BdsGetDeviceHd (

+  IN  EFI_DEVICE_PATH*  RemovableDevicePath,

+  OUT EFI_HANDLE*       DeviceHandle,

+  OUT EFI_DEVICE_PATH** NewDevicePath

+  )

+{

+  EFI_STATUS                    Status;

+  UINTN                         Index;

+  UINTN                         PartitionHandleCount;

+  EFI_HANDLE                    *PartitionBuffer;

+  EFI_DEVICE_PATH*              PartitionDevicePath;

+  EFI_DEVICE_PATH*              TmpDevicePath;

+  HARDDRIVE_DEVICE_PATH*        HardDriveDevicePath1;

+  HARDDRIVE_DEVICE_PATH*        HardDriveDevicePath2;

+

+  // Get all the DiskIo handles

+  PartitionHandleCount = 0;

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &PartitionHandleCount, &PartitionBuffer);

+  if (EFI_ERROR (Status) || (PartitionHandleCount == 0)) {

+    return Status;

+  }

+

+  // Check if one of the handles matches the Hard Disk Description

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

+    Status = gBS->HandleProtocol (PartitionBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &PartitionDevicePath);

+    if (!EFI_ERROR (Status)) {

+      TmpDevicePath = PartitionDevicePath;

+      while (!IsDevicePathEnd (TmpDevicePath)) {

+        // Check if the Device Path node is a HD Removable device Path node

+        if (BdsIsRemovableHd (TmpDevicePath)) {

+          HardDriveDevicePath1 = (HARDDRIVE_DEVICE_PATH*)RemovableDevicePath;

+          HardDriveDevicePath2 = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;

+          if ((HardDriveDevicePath1->SignatureType == HardDriveDevicePath2->SignatureType) &&

+              (CompareGuid ((EFI_GUID *)HardDriveDevicePath1->Signature, (EFI_GUID *)HardDriveDevicePath2->Signature) == TRUE) &&

+              (HardDriveDevicePath1->PartitionNumber == HardDriveDevicePath2->PartitionNumber))

+          {

+            *DeviceHandle = PartitionBuffer[Index];

+            // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path

+            *NewDevicePath = AppendDevicePath (PartitionDevicePath, NextDevicePathNode (RemovableDevicePath));

+            return EFI_SUCCESS;

+          }

+        }

+        TmpDevicePath = NextDevicePathNode (TmpDevicePath);

+      }

+

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+/*BOOLEAN

+BdsIsRemovableCdrom (

+  IN  EFI_DEVICE_PATH*  DevicePath

+  )

+{

+  return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_CDROM_DP);

+}

+

+EFI_STATUS

+BdsGetDeviceCdrom (

+  IN  EFI_DEVICE_PATH*  RemovableDevicePath,

+  OUT EFI_HANDLE*       DeviceHandle,

+  OUT EFI_DEVICE_PATH** DevicePath

+  )

+{

+  ASSERT(0);

+  return EFI_UNSUPPORTED;

+}*/

+

+typedef BOOLEAN

+(*BDS_IS_REMOVABLE) (

+  IN  EFI_DEVICE_PATH*  DevicePath

+  );

+

+typedef EFI_STATUS

+(*BDS_GET_DEVICE) (

+  IN  EFI_DEVICE_PATH*  RemovableDevicePath,

+  OUT EFI_HANDLE*       DeviceHandle,

+  OUT EFI_DEVICE_PATH** DevicePath

+  );

+

+typedef struct {

+  BDS_IS_REMOVABLE    IsRemovable;

+  BDS_GET_DEVICE      GetDevice;

+} BDS_REMOVABLE_DEVICE_SUPPORT;

+

+BDS_REMOVABLE_DEVICE_SUPPORT  RemovableDeviceSupport[] = {

+  { BdsIsRemovableUsb, BdsGetDeviceUsb },

+  { BdsIsRemovableHd, BdsGetDeviceHd },

+  //{ BdsIsRemovableCdrom, BdsGetDeviceCdrom }

+};

+

+STATIC

+BOOLEAN

+IsRemovableDevice (

+  IN  EFI_DEVICE_PATH*  DevicePath

+  )

+{

+  UINTN             Index;

+  EFI_DEVICE_PATH*  TmpDevicePath;

+

+  TmpDevicePath = DevicePath;

+  while (!IsDevicePathEnd (TmpDevicePath)) {

+    for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {

+      if (RemovableDeviceSupport[Index].IsRemovable (TmpDevicePath)) {

+        return TRUE;

+      }

+    }

+    TmpDevicePath = NextDevicePathNode (TmpDevicePath);

+  }

+

+  return FALSE;

+}

+

+STATIC

+EFI_STATUS

+TryRemovableDevice (

+  IN  EFI_DEVICE_PATH*  DevicePath,

+  OUT EFI_HANDLE*       DeviceHandle,

+  OUT EFI_DEVICE_PATH** NewDevicePath

+  )

+{

+  EFI_STATUS        Status;

+  UINTN             Index;

+  EFI_DEVICE_PATH*  TmpDevicePath;

+  BDS_REMOVABLE_DEVICE_SUPPORT* RemovableDevice;

+  EFI_DEVICE_PATH* RemovableDevicePath;

+  BOOLEAN         RemovableFound;

+

+  RemovableDevice     = NULL;

+  RemovableDevicePath = NULL;

+  RemovableFound      = FALSE;

+  TmpDevicePath       = DevicePath;

+

+  while (!IsDevicePathEnd (TmpDevicePath) && !RemovableFound) {

+    for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {

+      RemovableDevice = &RemovableDeviceSupport[Index];

+      if (RemovableDevice->IsRemovable (TmpDevicePath)) {

+        RemovableDevicePath = TmpDevicePath;

+        RemovableFound = TRUE;

+        break;

+      }

+    }

+    TmpDevicePath = NextDevicePathNode (TmpDevicePath);

+  }

+

+  if (!RemovableFound) {

+    return EFI_NOT_FOUND;

+  }

+

+  // Search into the current started drivers

+  Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);

+  if (Status == EFI_NOT_FOUND) {

+    // Connect all the drivers

+    BdsConnectAllDrivers ();

+

+    // Search again into all the drivers

+    Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);

+  }

+

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+BdsConnectAndUpdateDevicePath (

+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,

+  OUT    EFI_HANDLE                *Handle,

+  OUT    EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath

+  )

+{

+  EFI_DEVICE_PATH*            Remaining;

+  EFI_DEVICE_PATH*            NewDevicePath;

+  EFI_STATUS                  Status;

+  EFI_HANDLE                  PreviousHandle;

+

+  if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PreviousHandle = NULL;

+  do {

+    Remaining = *DevicePath;

+

+    // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns

+    // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified

+    // to point to the remaining part of the device path

+    Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);

+

+    if (!EFI_ERROR (Status)) {

+      if (*Handle == PreviousHandle) {

+        //

+        // If no forward progress is made try invoking the Dispatcher.

+        // A new FV may have been added to the system and new drivers

+        // may now be found.

+        // Status == EFI_SUCCESS means a driver was dispatched

+        // Status == EFI_NOT_FOUND means no new drivers were dispatched

+        //

+        Status = gDS->Dispatch ();

+      }

+

+      if (!EFI_ERROR (Status)) {

+        PreviousHandle = *Handle;

+

+        // Recursive = FALSE: We do not want to start the whole device tree

+        Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);

+      }

+    }

+  } while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));

+

+  if (!EFI_ERROR (Status)) {

+    // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver

+    // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)

+    Remaining = *DevicePath;

+    Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);

+    if (!EFI_ERROR (Status)) {

+      Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);

+      if (EFI_ERROR (Status)) {

+        // If the last node is a Memory Map Device Path just return EFI_SUCCESS.

+        if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {

+            Status = EFI_SUCCESS;

+        }

+      }

+    }

+  } else if (!IsDevicePathEnd (Remaining) && !IsRemovableDevice (Remaining)) {

+

+    /*// If the remaining Device Path is a FilePath or MemoryMap then we consider the Device Path has been loaded correctly

+    if ((Remaining->Type == MEDIA_DEVICE_PATH) && (Remaining->SubType == MEDIA_FILEPATH_DP)) {

+      Status = EFI_SUCCESS;

+    } else if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {

+      Status = EFI_SUCCESS;

+    }*/

+

+    //TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath

+    Status = EFI_SUCCESS;

+  } else {

+    Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);

+    if (!EFI_ERROR (Status)) {

+      Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);

+      *DevicePath = NewDevicePath;

+      return Status;

+    }

+  }

+

+  if (RemainingDevicePath) {

+    *RemainingDevicePath = Remaining;

+  }

+

+  return Status;

+}

+

+/**

+  Connect a Device Path and return the handle of the driver that support this DevicePath

+

+  @param  DevicePath            Device Path of the File to connect

+  @param  Handle                Handle of the driver that support this DevicePath

+  @param  RemainingDevicePath   Remaining DevicePath nodes that do not match the driver DevicePath

+

+  @retval EFI_SUCCESS           A driver that matches the Device Path has been found

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL

+

+**/

+EFI_STATUS

+BdsConnectDevicePath (

+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,

+  OUT EFI_HANDLE                *Handle,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath

+  )

+{

+  return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);

+}

+

+BOOLEAN

+BdsFileSystemSupport (

+  IN EFI_DEVICE_PATH *DevicePath,

+  IN EFI_HANDLE Handle,

+  IN EFI_DEVICE_PATH *RemainingDevicePath

+  )

+{

+  EFI_STATUS  Status;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *FsProtocol;

+

+  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FsProtocol);

+

+  return (!EFI_ERROR (Status) && IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP));

+}

+

+EFI_STATUS

+BdsFileSystemLoadImage (

+  IN     EFI_DEVICE_PATH       *DevicePath,

+  IN     EFI_HANDLE            Handle,

+  IN     EFI_DEVICE_PATH       *RemainingDevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS  *Image,

+  OUT    UINTN                 *ImageSize

+  )

+{

+  EFI_STATUS                       Status;

+  FILEPATH_DEVICE_PATH             *FilePathDevicePath;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *FsProtocol;

+  EFI_FILE_PROTOCOL                *Fs;

+  EFI_FILE_INFO                    *FileInfo;

+  EFI_FILE_PROTOCOL                *File;

+  UINTN                            Size;

+

+  ASSERT (IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP));

+

+  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)RemainingDevicePath;

+

+  Status = gBS->OpenProtocol (

+                  Handle,

+                  &gEfiSimpleFileSystemProtocolGuid,

+                  (VOID**)&FsProtocol,

+                  gImageHandle,

+                  Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  // Try to Open the volume and get root directory

+  Status = FsProtocol->OpenVolume (FsProtocol, &Fs);

+  if (EFI_ERROR (Status)) {

+    goto CLOSE_PROTOCOL;

+  }

+

+  Status = Fs->Open (Fs, &File, FilePathDevicePath->PathName, EFI_FILE_MODE_READ, 0);

+  if (EFI_ERROR (Status)) {

+    goto CLOSE_PROTOCOL;

+  }

+

+  Size = 0;

+  File->GetInfo (File, &gEfiFileInfoGuid, &Size, NULL);

+  FileInfo = AllocatePool (Size);

+  Status = File->GetInfo (File, &gEfiFileInfoGuid, &Size, FileInfo);

+  if (EFI_ERROR (Status)) {

+    goto CLOSE_FILE;

+  }

+

+  // Get the file size

+  Size = FileInfo->FileSize;

+  if (ImageSize) {

+    *ImageSize = Size;

+  }

+  FreePool (FileInfo);

+

+  Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);

+  // Try to allocate in any pages if failed to allocate memory at the defined location

+  if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {

+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);

+  }

+  if (!EFI_ERROR (Status)) {

+    Status = File->Read (File, &Size, (VOID*)(UINTN)(*Image));

+  }

+

+CLOSE_FILE:

+  File->Close (File);

+

+CLOSE_PROTOCOL:

+  gBS->CloseProtocol (

+         Handle,

+         &gEfiSimpleFileSystemProtocolGuid,

+         gImageHandle,

+         Handle);

+

+  return Status;

+}

+

+BOOLEAN

+BdsMemoryMapSupport (

+  IN EFI_DEVICE_PATH *DevicePath,

+  IN EFI_HANDLE Handle,

+  IN EFI_DEVICE_PATH *RemainingDevicePath

+  )

+{

+  return IS_DEVICE_PATH_NODE (DevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP) ||

+         IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP);

+}

+

+EFI_STATUS

+BdsMemoryMapLoadImage (

+  IN     EFI_DEVICE_PATH *DevicePath,

+  IN     EFI_HANDLE Handle,

+  IN     EFI_DEVICE_PATH *RemainingDevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS* Image,

+  OUT    UINTN                 *ImageSize

+  )

+{

+  EFI_STATUS            Status;

+  MEMMAP_DEVICE_PATH*   MemMapPathDevicePath;

+  UINTN                 Size;

+

+  if (IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP)) {

+    MemMapPathDevicePath = (MEMMAP_DEVICE_PATH*)RemainingDevicePath;

+  } else {

+    ASSERT (IS_DEVICE_PATH_NODE (DevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP));

+    MemMapPathDevicePath = (MEMMAP_DEVICE_PATH*)DevicePath;

+  }

+

+  Size = MemMapPathDevicePath->EndingAddress - MemMapPathDevicePath->StartingAddress;

+  if (Size == 0) {

+      return EFI_INVALID_PARAMETER;

+  }

+

+  Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);

+  // Try to allocate in any pages if failed to allocate memory at the defined location

+  if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {

+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);

+  }

+  if (!EFI_ERROR (Status)) {

+    CopyMem ((VOID*)(UINTN)(*Image), (CONST VOID*)(UINTN)MemMapPathDevicePath->StartingAddress, Size);

+

+    if (ImageSize != NULL) {

+        *ImageSize = Size;

+    }

+  }

+

+  return Status;

+}

+

+BOOLEAN

+BdsFirmwareVolumeSupport (

+  IN EFI_DEVICE_PATH *DevicePath,

+  IN EFI_HANDLE Handle,

+  IN EFI_DEVICE_PATH *RemainingDevicePath

+  )

+{

+  return IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP);

+}

+

+EFI_STATUS

+BdsFirmwareVolumeLoadImage (

+  IN     EFI_DEVICE_PATH *DevicePath,

+  IN     EFI_HANDLE Handle,

+  IN     EFI_DEVICE_PATH *RemainingDevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS* Image,

+  OUT    UINTN                 *ImageSize

+  )

+{

+  EFI_STATUS            Status;

+  EFI_FIRMWARE_VOLUME2_PROTOCOL     *FwVol;

+  EFI_GUID                          *FvNameGuid;

+  EFI_SECTION_TYPE                  SectionType;

+  EFI_FV_FILETYPE                   FvType;

+  EFI_FV_FILE_ATTRIBUTES            Attrib;

+  UINT32                            AuthenticationStatus;

+  VOID* ImageBuffer;

+

+  ASSERT (IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP));

+

+  Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FwVol);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)RemainingDevicePath);

+  if (FvNameGuid == NULL) {

+    Status = EFI_INVALID_PARAMETER;

+  }

+

+  SectionType = EFI_SECTION_PE32;

+  AuthenticationStatus = 0;

+  //Note: ReadSection at the opposite of ReadFile does not allow to pass ImageBuffer == NULL to get the size of the file.

+  ImageBuffer = NULL;

+  Status = FwVol->ReadSection (

+                    FwVol,

+                    FvNameGuid,

+                    SectionType,

+                    0,

+                    &ImageBuffer,

+                    ImageSize,

+                    &AuthenticationStatus

+                    );

+  if (!EFI_ERROR (Status)) {

+#if 0

+    // In case the buffer has some address requirements, we must copy the buffer to a buffer following the requirements

+    if (Type != AllocateAnyPages) {

+      Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize),Image);

+      if (!EFI_ERROR (Status)) {

+        CopyMem ((VOID*)(UINTN)(*Image), ImageBuffer, *ImageSize);

+        FreePool (ImageBuffer);

+      }

+    }

+#else

+    // We must copy the buffer into a page allocations. Otherwise, the caller could call gBS->FreePages() on the pool allocation

+    Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);

+    // Try to allocate in any pages if failed to allocate memory at the defined location

+    if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {

+      Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);

+    }

+    if (!EFI_ERROR (Status)) {

+      CopyMem ((VOID*)(UINTN)(*Image), ImageBuffer, *ImageSize);

+      FreePool (ImageBuffer);

+    }

+#endif

+  } else {

+    // Try a raw file, since a PE32 SECTION does not exist

+    Status = FwVol->ReadFile (

+                        FwVol,

+                        FvNameGuid,

+                        NULL,

+                        ImageSize,

+                        &FvType,

+                        &Attrib,

+                        &AuthenticationStatus

+                        );

+    if (!EFI_ERROR (Status)) {

+      Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);

+      // Try to allocate in any pages if failed to allocate memory at the defined location

+      if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {

+        Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);

+      }

+      if (!EFI_ERROR (Status)) {

+        Status = FwVol->ReadFile (

+                                FwVol,

+                                FvNameGuid,

+                                (VOID*)(UINTN)(*Image),

+                                ImageSize,

+                                &FvType,

+                                &Attrib,

+                                &AuthenticationStatus

+                                );

+      }

+    }

+  }

+  return Status;

+}

+

+BOOLEAN

+BdsPxeSupport (

+  IN EFI_DEVICE_PATH*           DevicePath,

+  IN EFI_HANDLE                 Handle,

+  IN EFI_DEVICE_PATH*           RemainingDevicePath

+  )

+{

+  EFI_STATUS                  Status;

+  EFI_PXE_BASE_CODE_PROTOCOL* PxeBcProtocol;

+

+  if (!IsDevicePathEnd (RemainingDevicePath)) {

+    return FALSE;

+  }

+

+  Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+}

+

+EFI_STATUS

+BdsPxeLoadImage (

+  IN     EFI_DEVICE_PATH*       DevicePath,

+  IN     EFI_HANDLE             Handle,

+  IN     EFI_DEVICE_PATH*       RemainingDevicePath,

+  IN     EFI_ALLOCATE_TYPE      Type,

+  IN OUT EFI_PHYSICAL_ADDRESS   *Image,

+  OUT    UINTN                  *ImageSize

+  )

+{

+  EFI_STATUS              Status;

+  EFI_LOAD_FILE_PROTOCOL  *LoadFileProtocol;

+  UINTN                   BufferSize;

+  EFI_PXE_BASE_CODE_PROTOCOL *Pxe;

+

+  // Get Load File Protocol attached to the PXE protocol

+  Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFileProtocol);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = LoadFileProtocol->LoadFile (LoadFileProtocol, DevicePath, TRUE, &BufferSize, NULL);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(BufferSize), Image);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = LoadFileProtocol->LoadFile (LoadFileProtocol, DevicePath, TRUE, &BufferSize, (VOID*)(UINTN)(*Image));

+    if (!EFI_ERROR (Status) && (ImageSize != NULL)) {

+      *ImageSize = BufferSize;

+    }

+  }

+

+  if (Status == EFI_ALREADY_STARTED) {

+    Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);

+    if (!EFI_ERROR(Status)) {

+      // If PXE is already started, we stop it

+      Pxe->Stop (Pxe);

+      // And we try again

+      return BdsPxeLoadImage (DevicePath, Handle, RemainingDevicePath, Type, Image, ImageSize);

+    }

+  }

+  return Status;

+}

+

+BOOLEAN

+BdsTftpSupport (

+  IN EFI_DEVICE_PATH  *DevicePath,

+  IN EFI_HANDLE       Handle,

+  IN EFI_DEVICE_PATH  *RemainingDevicePath

+  )

+{

+  EFI_STATUS       Status;

+  EFI_DEVICE_PATH  *NextDevicePath;

+  VOID             *Interface;

+

+  // Validate the Remaining Device Path

+  if (IsDevicePathEnd (RemainingDevicePath)) {

+    return FALSE;

+  }

+  if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP) &&

+      !IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv6_DP)) {

+    return FALSE;

+  }

+  NextDevicePath = NextDevicePathNode (RemainingDevicePath);

+  if (IsDevicePathEnd (NextDevicePath)) {

+    return FALSE;

+  }

+  if (!IS_DEVICE_PATH_NODE (NextDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP)) {

+    return FALSE;

+  }

+

+  Status = gBS->HandleProtocol (

+                  Handle, &gEfiDevicePathProtocolGuid,

+                  &Interface

+                  );

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  //

+  // Check that the controller (identified by its handle "Handle") supports the

+  // MTFTPv4 Service Binding Protocol. If it does, it means that it supports the

+  // EFI MTFTPv4 Protocol needed to download the image through TFTP.

+  //

+  Status = gBS->HandleProtocol (

+                  Handle, &gEfiMtftp4ServiceBindingProtocolGuid,

+                  &Interface

+                  );

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Worker function that get the size in numbers of bytes of a file from a TFTP

+  server before to download the file.

+

+  @param[in]   Mtftp4    MTFTP4 protocol interface

+  @param[in]   FilePath  Path of the file, Ascii encoded

+  @param[out]  FileSize  Address where to store the file size in number of

+                         bytes.

+

+  @retval  EFI_SUCCESS   The size of the file was returned.

+  @retval  !EFI_SUCCESS  The size of the file was not returned.

+

+**/

+STATIC

+EFI_STATUS

+Mtftp4GetFileSize (

+  IN  EFI_MTFTP4_PROTOCOL  *Mtftp4,

+  IN  CHAR8                *FilePath,

+  OUT UINT64               *FileSize

+  )

+{

+  EFI_STATUS         Status;

+  EFI_MTFTP4_OPTION  ReqOpt[1];

+  EFI_MTFTP4_PACKET  *Packet;

+  UINT32             PktLen;

+  EFI_MTFTP4_OPTION  *TableOfOptions;

+  EFI_MTFTP4_OPTION  *Option;

+  UINT32             OptCnt;

+  UINT8              OptBuf[128];

+

+  ReqOpt[0].OptionStr = (UINT8*)"tsize";

+  OptBuf[0] = '0';

+  OptBuf[1] = 0;

+  ReqOpt[0].ValueStr = OptBuf;

+

+  Status = Mtftp4->GetInfo (

+             Mtftp4,

+             NULL,

+             (UINT8*)FilePath,

+             NULL,

+             1,

+             ReqOpt,

+             &PktLen,

+             &Packet

+             );

+

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  Status = Mtftp4->ParseOptions (

+                     Mtftp4,

+                     PktLen,

+                     Packet,

+                     (UINT32 *) &OptCnt,

+                     &TableOfOptions

+                     );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  Option = TableOfOptions;

+  while (OptCnt != 0) {

+    if (AsciiStrnCmp ((CHAR8 *)Option->OptionStr, "tsize", 5) == 0) {

+      *FileSize = AsciiStrDecimalToUint64 ((CHAR8 *)Option->ValueStr);

+      break;

+    }

+    OptCnt--;

+    Option++;

+  }

+  FreePool (TableOfOptions);

+

+  if (OptCnt == 0) {

+    Status = EFI_UNSUPPORTED;

+  }

+

+Error :

+

+  return Status;

+}

+

+/**

+  Update the progress of a file download

+  This procedure is called each time a new TFTP packet is received.

+

+  @param[in]  This       MTFTP4 protocol interface

+  @param[in]  Token      Parameters for the download of the file

+  @param[in]  PacketLen  Length of the packet

+  @param[in]  Packet     Address of the packet

+

+  @retval  EFI_SUCCESS  All packets are accepted.

+

+**/

+STATIC

+EFI_STATUS

+Mtftp4CheckPacket (

+  IN EFI_MTFTP4_PROTOCOL  *This,

+  IN EFI_MTFTP4_TOKEN     *Token,

+  IN UINT16               PacketLen,

+  IN EFI_MTFTP4_PACKET    *Packet

+  )

+{

+  BDS_TFTP_CONTEXT  *Context;

+  CHAR16            Progress[TFTP_PROGRESS_MESSAGE_SIZE];

+  UINT64            NbOfKb;

+  UINTN             Index;

+  UINTN             LastStep;

+  UINTN             Step;

+  UINT64            LastNbOf50Kb;

+  UINT64            NbOf50Kb;

+

+  if ((NTOHS (Packet->OpCode)) == EFI_MTFTP4_OPCODE_DATA) {

+    Context = (BDS_TFTP_CONTEXT*)Token->Context;

+

+    if (Context->DownloadedNbOfBytes == 0) {

+      if (Context->FileSize > 0) {

+        Print (L"%s       0 Kb", mTftpProgressFrame);

+      } else {

+        Print (L"    0 Kb");

+      }

+    }

+

+    //

+    // The data is the packet are prepended with two UINT16 :

+    // . OpCode = EFI_MTFTP4_OPCODE_DATA

+    // . Block  = the number of this block of data

+    //

+    Context->DownloadedNbOfBytes += PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block);

+    NbOfKb = Context->DownloadedNbOfBytes / 1024;

+

+    Progress[0] = L'\0';

+    if (Context->FileSize > 0) {

+      LastStep  = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;

+      Step      = (Context->DownloadedNbOfBytes   * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;

+      if (Step > LastStep) {

+        Print (mTftpProgressDelete);

+        StrCpy (Progress, mTftpProgressFrame);

+        for (Index = 1; Index < Step; Index++) {

+          Progress[Index] = L'=';

+        }

+        Progress[Step] = L'>';

+

+        UnicodeSPrint (

+          Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1,

+          sizeof (Progress) - sizeof (mTftpProgressFrame),

+          L" %7d Kb",

+          NbOfKb

+          );

+        Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;

+      }

+    } else {

+      //

+      // Case when we do not know the size of the final file.

+      // We print the updated size every 50KB of downloaded data

+      //

+      LastNbOf50Kb = Context->LastReportedNbOfBytes / (50*1024);

+      NbOf50Kb     = Context->DownloadedNbOfBytes   / (50*1024);

+      if (NbOf50Kb > LastNbOf50Kb) {

+        Print (L"\b\b\b\b\b\b\b\b\b\b");

+        UnicodeSPrint (Progress, sizeof (Progress), L"%7d Kb", NbOfKb);

+        Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;

+      }

+    }

+    if (Progress[0] != L'\0') {

+      Print (L"%s", Progress);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Download an image from a TFTP server

+

+  @param[in]   DevicePath           Device path of the TFTP boot option

+  @param[in]   ControllerHandle     Handle of the network controller

+  @param[in]   RemainingDevicePath  Device path of the TFTP boot option but

+                                    the first node that identifies the network controller

+  @param[in]   Type                 Type to allocate memory pages

+  @param[out]  Image                Address of the bufer where the image is stored in

+                                    case of success

+  @param[out]  ImageSize            Size in number of bytes of the i;age in case of

+                                    success

+

+  @retval  EFI_SUCCESS   The image was returned.

+  @retval  !EFI_SUCCESS  Something went wrong.

+

+**/

+EFI_STATUS

+BdsTftpLoadImage (

+  IN     EFI_DEVICE_PATH*       DevicePath,

+  IN     EFI_HANDLE             ControllerHandle,

+  IN     EFI_DEVICE_PATH*       RemainingDevicePath,

+  IN     EFI_ALLOCATE_TYPE      Type,

+  IN OUT EFI_PHYSICAL_ADDRESS   *Image,

+  OUT    UINTN                  *ImageSize

+  )

+{

+  EFI_STATUS               Status;

+  EFI_HANDLE               Dhcp4ChildHandle;

+  EFI_DHCP4_PROTOCOL       *Dhcp4;

+  BOOLEAN                  Dhcp4ToStop;

+  EFI_HANDLE               Mtftp4ChildHandle;

+  EFI_MTFTP4_PROTOCOL      *Mtftp4;

+  DHCP4_OPTION             ParaList;

+  EFI_DHCP4_PACKET_OPTION  *OptionList[2];

+  EFI_DHCP4_CONFIG_DATA    Dhcp4CfgData;

+  EFI_DHCP4_MODE_DATA      Dhcp4Mode;

+  EFI_MTFTP4_CONFIG_DATA   Mtftp4CfgData;

+  IPv4_DEVICE_PATH         *IPv4DevicePathNode;

+  FILEPATH_DEVICE_PATH     *FilePathDevicePathNode;

+  CHAR8                    *AsciiFilePath;

+  EFI_MTFTP4_TOKEN         Mtftp4Token;

+  UINT64                   FileSize;

+  UINT64                   TftpBufferSize;

+  BDS_TFTP_CONTEXT         *TftpContext;

+

+  ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP));

+  IPv4DevicePathNode = (IPv4_DEVICE_PATH*)RemainingDevicePath;

+

+  Dhcp4ChildHandle  = NULL;

+  Dhcp4             = NULL;

+  Dhcp4ToStop       = FALSE;

+  Mtftp4ChildHandle = NULL;

+  Mtftp4            = NULL;

+  AsciiFilePath     = NULL;

+  TftpContext       = NULL;

+

+  if (!IPv4DevicePathNode->StaticIpAddress) {

+    //

+    // Using the DHCP4 Service Binding Protocol, create a child handle of the DHCP4 service and

+    // install the DHCP4 protocol on it. Then, open the DHCP protocol.

+    //

+    Status = NetLibCreateServiceChild (

+               ControllerHandle,

+               gImageHandle,

+               &gEfiDhcp4ServiceBindingProtocolGuid,

+               &Dhcp4ChildHandle

+               );

+    if (!EFI_ERROR (Status)) {

+      Status = gBS->OpenProtocol (

+                      Dhcp4ChildHandle,

+                      &gEfiDhcp4ProtocolGuid,

+                      (VOID **) &Dhcp4,

+                      gImageHandle,

+                      ControllerHandle,

+                      EFI_OPEN_PROTOCOL_BY_DRIVER

+                      );

+    }

+    if (EFI_ERROR (Status)) {

+      Print (L"Unable to open DHCP4 protocol\n");

+      goto Error;

+    }

+  }

+

+  //

+  // Using the MTFTP4 Service Binding Protocol, create a child handle of the MTFTP4 service and

+  // install the MTFTP4 protocol on it. Then, open the MTFTP4 protocol.

+  //

+  Status = NetLibCreateServiceChild (

+             ControllerHandle,

+             gImageHandle,

+             &gEfiMtftp4ServiceBindingProtocolGuid,

+             &Mtftp4ChildHandle

+             );

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->OpenProtocol (

+                    Mtftp4ChildHandle,

+                    &gEfiMtftp4ProtocolGuid,

+                    (VOID **) &Mtftp4,

+                    gImageHandle,

+                    ControllerHandle,

+                    EFI_OPEN_PROTOCOL_BY_DRIVER

+                    );

+  }

+  if (EFI_ERROR (Status)) {

+    Print (L"Unable to open MTFTP4 protocol\n");

+    goto Error;

+  }

+

+  if (!IPv4DevicePathNode->StaticIpAddress) {

+    //

+    // Configure the DHCP4, all default settings. It is acceptable for the configuration to

+    // fail if the return code is equal to EFI_ACCESS_DENIED which means that the configuration

+    // has been done by another instance of the DHCP4 protocol or that the DHCP configuration

+    // process has been started but is not completed yet.

+    //

+    ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));

+    ParaList.Head.OpCode     = DHCP_TAG_PARA_LIST;

+    ParaList.Head.Length     = 2;

+    ParaList.Head.Data[0]    = DHCP_TAG_NETMASK;

+    ParaList.Route           = DHCP_TAG_ROUTER;

+    OptionList[0]            = &ParaList.Head;

+    Dhcp4CfgData.OptionCount = 1;

+    Dhcp4CfgData.OptionList  = OptionList;

+

+    Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);

+    if (EFI_ERROR (Status)) {

+      if (Status != EFI_ACCESS_DENIED) {

+        Print (L"Error while configuring the DHCP4 protocol\n");

+        goto Error;

+      }

+    }

+

+    //

+    // Start the DHCP configuration. This may have already been done thus do not leave in error

+    // if the return code is EFI_ALREADY_STARTED.

+    //

+    Status = Dhcp4->Start (Dhcp4, NULL);

+    if (EFI_ERROR (Status)) {

+      if (Status != EFI_ALREADY_STARTED) {

+        Print (L"DHCP configuration failed\n");

+        goto Error;

+      }

+    } else {

+      Dhcp4ToStop = TRUE;

+    }

+

+    Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);

+    if (EFI_ERROR (Status)) {

+      goto Error;

+    }

+

+    if (Dhcp4Mode.State != Dhcp4Bound) {

+      Status = EFI_TIMEOUT;

+      Print (L"DHCP configuration failed\n");

+      goto Error;

+    }

+  }

+

+  //

+  // Configure the TFTP4 protocol

+  //

+

+  ZeroMem (&Mtftp4CfgData, sizeof (EFI_MTFTP4_CONFIG_DATA));

+  Mtftp4CfgData.UseDefaultSetting = FALSE;

+  Mtftp4CfgData.TimeoutValue      = 4;

+  Mtftp4CfgData.TryCount          = 6;

+

+  if (IPv4DevicePathNode->StaticIpAddress) {

+    CopyMem (&Mtftp4CfgData.StationIp , &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));

+    CopyMem (&Mtftp4CfgData.SubnetMask, &IPv4DevicePathNode->SubnetMask, sizeof (EFI_IPv4_ADDRESS));

+    CopyMem (&Mtftp4CfgData.GatewayIp , &IPv4DevicePathNode->GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));

+  } else {

+    CopyMem (&Mtftp4CfgData.StationIp , &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));

+    CopyMem (&Mtftp4CfgData.SubnetMask, &Dhcp4Mode.SubnetMask   , sizeof (EFI_IPv4_ADDRESS));

+    CopyMem (&Mtftp4CfgData.GatewayIp , &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));

+  }

+

+  CopyMem (&Mtftp4CfgData.ServerIp  , &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));

+

+  Status = Mtftp4->Configure (Mtftp4, &Mtftp4CfgData);

+  if (EFI_ERROR (Status)) {

+    Print (L"Error while configuring the MTFTP4 protocol\n");

+    goto Error;

+  }

+

+  //

+  // Convert the Unicode path of the file to Ascii

+  //

+

+  FilePathDevicePathNode = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1);

+  AsciiFilePath = AllocatePool ((StrLen (FilePathDevicePathNode->PathName) + 1) * sizeof (CHAR8));

+  if (AsciiFilePath == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+  UnicodeStrToAsciiStr (FilePathDevicePathNode->PathName, AsciiFilePath);

+

+  //

+  // Try to get the size of the file in bytes from the server. If it fails,

+  // start with a 8MB buffer to download the file.

+  //

+  FileSize = 0;

+  if (Mtftp4GetFileSize (Mtftp4, AsciiFilePath, &FileSize) == EFI_SUCCESS) {

+    TftpBufferSize = FileSize;

+  } else {

+    TftpBufferSize = SIZE_8MB;

+  }

+

+  TftpContext = AllocatePool (sizeof (BDS_TFTP_CONTEXT));

+  if (TftpContext == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+  TftpContext->FileSize = FileSize;

+

+  for (; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize);

+         TftpBufferSize = (TftpBufferSize + SIZE_8MB) & (~(SIZE_8MB-1))) {

+    //

+    // Allocate a buffer to hold the whole file.

+    //

+    Status = gBS->AllocatePages (

+                    Type,

+                    EfiBootServicesCode,

+                    EFI_SIZE_TO_PAGES (TftpBufferSize),

+                    Image

+                    );

+    if (EFI_ERROR (Status)) {

+      Print (L"Failed to allocate space for image\n");

+      goto Error;

+    }

+

+    TftpContext->DownloadedNbOfBytes   = 0;

+    TftpContext->LastReportedNbOfBytes = 0;

+

+    ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));

+    Mtftp4Token.Filename    = (UINT8*)AsciiFilePath;

+    Mtftp4Token.BufferSize  = TftpBufferSize;

+    Mtftp4Token.Buffer      = (VOID *)(UINTN)*Image;

+    Mtftp4Token.CheckPacket = Mtftp4CheckPacket;

+    Mtftp4Token.Context     = (VOID*)TftpContext;

+

+    Print (L"Downloading the file <%s> from the TFTP server\n", FilePathDevicePathNode->PathName);

+    Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);

+    Print (L"\n");

+    if (EFI_ERROR (Status)) {

+      gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));

+      if (Status == EFI_BUFFER_TOO_SMALL) {

+        Print (L"Downloading failed, file larger than expected.\n");

+        continue;

+      } else {

+        goto Error;

+      }

+    }

+

+    *ImageSize = Mtftp4Token.BufferSize;

+    break;

+  }

+

+Error:

+  if (Dhcp4ChildHandle != NULL) {

+    if (Dhcp4 != NULL) {

+      if (Dhcp4ToStop) {

+        Dhcp4->Stop (Dhcp4);

+      }

+      gBS->CloseProtocol (

+             Dhcp4ChildHandle,

+             &gEfiDhcp4ProtocolGuid,

+             gImageHandle,

+             ControllerHandle

+            );

+    }

+    NetLibDestroyServiceChild (

+      ControllerHandle,

+      gImageHandle,

+      &gEfiDhcp4ServiceBindingProtocolGuid,

+      Dhcp4ChildHandle

+      );

+  }

+

+  if (Mtftp4ChildHandle != NULL) {

+    if (Mtftp4 != NULL) {

+      if (AsciiFilePath != NULL) {

+        FreePool (AsciiFilePath);

+      }

+      if (TftpContext != NULL) {

+        FreePool (TftpContext);

+      }

+      gBS->CloseProtocol (

+             Mtftp4ChildHandle,

+             &gEfiMtftp4ProtocolGuid,

+             gImageHandle,

+             ControllerHandle

+            );

+    }

+    NetLibDestroyServiceChild (

+      ControllerHandle,

+      gImageHandle,

+      &gEfiMtftp4ServiceBindingProtocolGuid,

+      Mtftp4ChildHandle

+      );

+  }

+

+  if (EFI_ERROR (Status)) {

+    Print (L"Failed to download the file - Error=%r\n", Status);

+  }

+

+  return Status;

+}

+

+BDS_FILE_LOADER FileLoaders[] = {

+    { BdsFileSystemSupport, BdsFileSystemLoadImage },

+    { BdsFirmwareVolumeSupport, BdsFirmwareVolumeLoadImage },

+    //{ BdsLoadFileSupport, BdsLoadFileLoadImage },

+    { BdsMemoryMapSupport, BdsMemoryMapLoadImage },

+    { BdsPxeSupport, BdsPxeLoadImage },

+    { BdsTftpSupport, BdsTftpLoadImage },

+    { NULL, NULL }

+};

+

+EFI_STATUS

+BdsLoadImageAndUpdateDevicePath (

+  IN OUT EFI_DEVICE_PATH       **DevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS* Image,

+  OUT    UINTN                 *FileSize

+  )

+{

+  EFI_STATUS      Status;

+  EFI_HANDLE      Handle;

+  EFI_DEVICE_PATH *RemainingDevicePath;

+  BDS_FILE_LOADER*  FileLoader;

+

+  Status = BdsConnectAndUpdateDevicePath (DevicePath, &Handle, &RemainingDevicePath);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  FileLoader = FileLoaders;

+  while (FileLoader->Support != NULL) {

+    if (FileLoader->Support (*DevicePath, Handle, RemainingDevicePath)) {

+      return FileLoader->LoadImage (*DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);

+    }

+    FileLoader++;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+BdsLoadImage (

+  IN     EFI_DEVICE_PATH       *DevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS* Image,

+  OUT    UINTN                 *FileSize

+  )

+{

+  return BdsLoadImageAndUpdateDevicePath (&DevicePath, Type, Image, FileSize);

+}

+

+/**

+  Start an EFI Application from a Device Path

+

+  @param  ParentImageHandle     Handle of the calling image

+  @param  DevicePath            Location of the EFI Application

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found

+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsStartEfiApplication (

+  IN EFI_HANDLE                  ParentImageHandle,

+  IN EFI_DEVICE_PATH_PROTOCOL    *DevicePath,

+  IN UINTN                       LoadOptionsSize,

+  IN VOID*                       LoadOptions

+  )

+{

+  EFI_STATUS                   Status;

+  EFI_HANDLE                   ImageHandle;

+  EFI_PHYSICAL_ADDRESS         BinaryBuffer;

+  UINTN                        BinarySize;

+  EFI_LOADED_IMAGE_PROTOCOL*   LoadedImage;

+

+  // Find the nearest supported file loader

+  Status = BdsLoadImageAndUpdateDevicePath (&DevicePath, AllocateAnyPages, &BinaryBuffer, &BinarySize);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  // Load the image from the Buffer with Boot Services function

+  Status = gBS->LoadImage (TRUE, ParentImageHandle, DevicePath, (VOID*)(UINTN)BinaryBuffer, BinarySize, &ImageHandle);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  // Passed LoadOptions to the EFI Application

+  if (LoadOptionsSize != 0) {

+    Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    LoadedImage->LoadOptionsSize  = LoadOptionsSize;

+    LoadedImage->LoadOptions      = LoadOptions;

+  }

+

+  // Before calling the image, enable the Watchdog Timer for  the 5 Minute period

+  gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);

+  // Start the image

+  Status = gBS->StartImage (ImageHandle, NULL, NULL);

+  // Clear the Watchdog Timer after the image returns

+  gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsHelper.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsHelper.c
new file mode 100644
index 0000000..7f83c2b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsHelper.c
@@ -0,0 +1,359 @@
+/** @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 "BdsInternal.h"

+

+#include <Library/HobLib.h>

+#include <Library/TimerLib.h>

+#include <Library/PrintLib.h>

+#include <Library/SerialPortLib.h>

+

+STATIC CHAR8 *mTokenList[] = {

+  /*"SEC",*/

+  "PEI",

+  "DXE",

+  "BDS",

+  NULL

+};

+

+EFI_STATUS

+ShutdownUefiBootServices (

+  VOID

+  )

+{

+  EFI_STATUS              Status;

+  UINTN                   MemoryMapSize;

+  EFI_MEMORY_DESCRIPTOR   *MemoryMap;

+  UINTN                   MapKey;

+  UINTN                   DescriptorSize;

+  UINT32                  DescriptorVersion;

+  UINTN                   Pages;

+

+  MemoryMap = NULL;

+  MemoryMapSize = 0;

+  Pages = 0;

+

+  do {

+    Status = gBS->GetMemoryMap (

+                    &MemoryMapSize,

+                    MemoryMap,

+                    &MapKey,

+                    &DescriptorSize,

+                    &DescriptorVersion

+                    );

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+

+      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;

+      MemoryMap = AllocatePages (Pages);

+

+      //

+      // Get System MemoryMap

+      //

+      Status = gBS->GetMemoryMap (

+                      &MemoryMapSize,

+                      MemoryMap,

+                      &MapKey,

+                      &DescriptorSize,

+                      &DescriptorVersion

+                      );

+    }

+

+    // Don't do anything between the GetMemoryMap() and ExitBootServices()

+    if (!EFI_ERROR(Status)) {

+      Status = gBS->ExitBootServices (gImageHandle, MapKey);

+      if (EFI_ERROR(Status)) {

+        FreePages (MemoryMap, Pages);

+        MemoryMap = NULL;

+        MemoryMapSize = 0;

+      }

+    }

+  } while (EFI_ERROR(Status));

+

+  return Status;

+}

+

+/**

+  Connect all DXE drivers

+

+  @retval EFI_SUCCESS           All drivers have been connected

+  @retval EFI_NOT_FOUND         No handles match the search.

+  @retval EFI_OUT_OF_RESOURCES  There is not resource pool memory to store the matching results.

+

+**/

+EFI_STATUS

+BdsConnectAllDrivers (

+  VOID

+  )

+{

+  UINTN                     HandleCount, Index;

+  EFI_HANDLE                *HandleBuffer;

+  EFI_STATUS                Status;

+

+  do {

+    // Locate all the driver handles

+    Status = gBS->LocateHandleBuffer (

+                AllHandles,

+                NULL,

+                NULL,

+                &HandleCount,

+                &HandleBuffer

+                );

+    if (EFI_ERROR (Status)) {

+      break;

+    }

+

+    // Connect every handles

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

+      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);

+    }

+

+    if (HandleBuffer != NULL) {

+      FreePool (HandleBuffer);

+    }

+

+    // Check if new handles have been created after the start of the previous handles

+    Status = gDS->Dispatch ();

+  } while (!EFI_ERROR(Status));

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+InsertSystemMemoryResources (

+  LIST_ENTRY *ResourceList,

+  EFI_HOB_RESOURCE_DESCRIPTOR *ResHob

+  )

+{

+  BDS_SYSTEM_MEMORY_RESOURCE  *NewResource;

+  LIST_ENTRY                  *Link;

+  LIST_ENTRY                  *NextLink;

+  LIST_ENTRY                  AttachedResources;

+  BDS_SYSTEM_MEMORY_RESOURCE  *Resource;

+  EFI_PHYSICAL_ADDRESS        NewResourceEnd;

+

+  if (IsListEmpty (ResourceList)) {

+    NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));

+    NewResource->PhysicalStart = ResHob->PhysicalStart;

+    NewResource->ResourceLength = ResHob->ResourceLength;

+    InsertTailList (ResourceList, &NewResource->Link);

+    return EFI_SUCCESS;

+  }

+

+  InitializeListHead (&AttachedResources);

+

+  Link = ResourceList->ForwardLink;

+  ASSERT (Link != NULL);

+  while (Link != ResourceList) {

+    Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;

+

+    // Sanity Check. The resources should not overlapped.

+    ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));

+    ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&

+        ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));

+

+    // The new resource is attached after this resource descriptor

+    if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {

+      Resource->ResourceLength =  Resource->ResourceLength + ResHob->ResourceLength;

+

+      NextLink = RemoveEntryList (&Resource->Link);

+      InsertTailList (&AttachedResources, &Resource->Link);

+      Link = NextLink;

+    }

+    // The new resource is attached before this resource descriptor

+    else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {

+      Resource->PhysicalStart = ResHob->PhysicalStart;

+      Resource->ResourceLength =  Resource->ResourceLength + ResHob->ResourceLength;

+

+      NextLink = RemoveEntryList (&Resource->Link);

+      InsertTailList (&AttachedResources, &Resource->Link);

+      Link = NextLink;

+    } else {

+      Link = Link->ForwardLink;

+    }

+  }

+

+  if (!IsListEmpty (&AttachedResources)) {

+    // See if we can merge the attached resource with other resources

+

+    NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);

+    Link = RemoveEntryList (&NewResource->Link);

+    while (!IsListEmpty (&AttachedResources)) {

+      // Merge resources

+      Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;

+

+      // Ensure they overlap each other

+      ASSERT(

+          ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||

+          (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))

+      );

+

+      NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);

+      NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);

+      NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;

+

+      Link = RemoveEntryList (Link);

+    }

+  } else {

+    // None of the Resource of the list is attached to this ResHob. Create a new entry for it

+    NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));

+    NewResource->PhysicalStart = ResHob->PhysicalStart;

+    NewResource->ResourceLength = ResHob->ResourceLength;

+  }

+  InsertTailList (ResourceList, &NewResource->Link);

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetSystemMemoryResources (

+  IN  LIST_ENTRY *ResourceList

+  )

+{

+  EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;

+

+  InitializeListHead (ResourceList);

+

+  // Find the first System Memory Resource Descriptor

+  ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);

+  while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {

+    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));

+  }

+

+  // Did not find any

+  if (ResHob == NULL) {

+    return EFI_NOT_FOUND;

+  } else {

+    InsertSystemMemoryResources (ResourceList, ResHob);

+  }

+

+  ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));

+  while (ResHob != NULL) {

+    if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {

+      InsertSystemMemoryResources (ResourceList, ResHob);

+    }

+    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));

+  }

+

+  return EFI_SUCCESS;

+}

+

+VOID

+PrintPerformance (

+  VOID

+  )

+{

+  UINTN       Key;

+  CONST VOID  *Handle;

+  CONST CHAR8 *Token, *Module;

+  UINT64      Start, Stop, TimeStamp;

+  UINT64      Delta, TicksPerSecond, Milliseconds;

+  UINTN       Index;

+  CHAR8       Buffer[100];

+  UINTN       CharCount;

+  BOOLEAN     CountUp;

+

+  TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);

+  if (Start < Stop) {

+    CountUp = TRUE;

+  } else {

+    CountUp = FALSE;

+  }

+

+  TimeStamp = 0;

+  Key       = 0;

+  do {

+    Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);

+    if (Key != 0) {

+      for (Index = 0; mTokenList[Index] != NULL; Index++) {

+        if (AsciiStriCmp (mTokenList[Index], Token) == 0) {

+          Delta = CountUp?(Stop - Start):(Start - Stop);

+          TimeStamp += Delta;

+          Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);

+          CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"%6a %6ld ms\n", Token, Milliseconds);

+          SerialPortWrite ((UINT8 *) Buffer, CharCount);

+          break;

+        }

+      }

+    }

+  } while (Key != 0);

+

+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));

+  SerialPortWrite ((UINT8 *) Buffer, CharCount);

+}

+

+EFI_STATUS

+GetGlobalEnvironmentVariable (

+  IN     CONST CHAR16*   VariableName,

+  IN     VOID*           DefaultValue,

+  IN OUT UINTN*          Size,

+  OUT    VOID**          Value

+  )

+{

+  return GetEnvironmentVariable (VariableName, &gEfiGlobalVariableGuid,

+           DefaultValue, Size, Value);

+}

+

+EFI_STATUS

+GetEnvironmentVariable (

+  IN     CONST CHAR16*   VariableName,

+  IN     EFI_GUID*       VendorGuid,

+  IN     VOID*           DefaultValue,

+  IN OUT UINTN*          Size,

+  OUT    VOID**          Value

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       VariableSize;

+

+  // Try to get the variable size.

+  *Value = NULL;

+  VariableSize = 0;

+  Status = gRT->GetVariable ((CHAR16 *) VariableName, VendorGuid, NULL, &VariableSize, *Value);

+  if (Status == EFI_NOT_FOUND) {

+    if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {

+      // If the environment variable does not exist yet then set it with the default value

+      Status = gRT->SetVariable (

+                    (CHAR16*)VariableName,

+                    VendorGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    *Size,

+                    DefaultValue

+                    );

+      *Value = AllocateCopyPool (*Size, DefaultValue);

+    } else {

+      return EFI_NOT_FOUND;

+    }

+  } else if (Status == EFI_BUFFER_TOO_SMALL) {

+    // Get the environment variable value

+    *Value = AllocatePool (VariableSize);

+    if (*Value == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    Status = gRT->GetVariable ((CHAR16 *)VariableName, VendorGuid, NULL, &VariableSize, *Value);

+    if (EFI_ERROR (Status)) {

+      FreePool(*Value);

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (Size) {

+      *Size = VariableSize;

+    }

+  } else {

+    *Value = AllocateCopyPool (*Size, DefaultValue);

+    return Status;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsInternal.h b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsInternal.h
new file mode 100644
index 0000000..602fd8d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsInternal.h
@@ -0,0 +1,104 @@
+/** @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.

+*

+**/

+

+#ifndef __BDS_INTERNAL_H__

+#define __BDS_INTERNAL_H__

+

+#include <PiDxe.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/HobLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BdsLib.h>

+#include <Library/PcdLib.h>

+#include <Library/PerformanceLib.h>

+#include <Library/PrintLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+

+#include <Guid/ArmMpCoreInfo.h>

+#include <Guid/GlobalVariable.h>

+#include <Guid/FileInfo.h>

+

+#include <Protocol/DevicePath.h>

+#include <Protocol/DevicePathFromText.h>

+#include <Protocol/SimpleFileSystem.h>

+#include <Protocol/FirmwareVolume2.h>

+#include <Protocol/LoadFile.h>

+#include <Protocol/PxeBaseCode.h>

+

+#include <Uefi.h>

+

+typedef BOOLEAN (*BDS_FILE_LOADER_SUPPORT) (

+  IN EFI_DEVICE_PATH            *DevicePath,

+  IN EFI_HANDLE                 Handle,

+  IN EFI_DEVICE_PATH            *RemainingDevicePath

+  );

+

+typedef EFI_STATUS (*BDS_FILE_LOADER_LOAD_IMAGE) (

+  IN     EFI_DEVICE_PATH        *DevicePath,

+  IN     EFI_HANDLE             Handle,

+  IN     EFI_DEVICE_PATH        *RemainingDevicePath,

+  IN     EFI_ALLOCATE_TYPE      Type,

+  IN OUT EFI_PHYSICAL_ADDRESS*  Image,

+  OUT    UINTN                  *ImageSize

+  );

+

+typedef struct {

+  BDS_FILE_LOADER_SUPPORT     Support;

+  BDS_FILE_LOADER_LOAD_IMAGE  LoadImage;

+} BDS_FILE_LOADER;

+

+typedef struct _BDS_SYSTEM_MEMORY_RESOURCE {

+  LIST_ENTRY                  Link; // This attribute must be the first entry of this structure (to avoid pointer computation)

+  EFI_PHYSICAL_ADDRESS        PhysicalStart;

+  UINT64                      ResourceLength;

+} BDS_SYSTEM_MEMORY_RESOURCE;

+

+typedef struct {

+  UINT64  FileSize;

+  UINT64  DownloadedNbOfBytes;

+  UINT64  LastReportedNbOfBytes;

+} BDS_TFTP_CONTEXT;

+

+// BdsHelper.c

+EFI_STATUS

+ShutdownUefiBootServices (

+  VOID

+  );

+

+EFI_STATUS

+GetSystemMemoryResources (

+  LIST_ENTRY *ResourceList

+  );

+

+VOID

+PrintPerformance (

+  VOID

+  );

+

+EFI_STATUS

+BdsLoadImage (

+  IN     EFI_DEVICE_PATH       *DevicePath,

+  IN     EFI_ALLOCATE_TYPE     Type,

+  IN OUT EFI_PHYSICAL_ADDRESS* Image,

+  OUT    UINTN                 *FileSize

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLib.inf b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLib.inf
new file mode 100644
index 0000000..6d6a2df
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLib.inf
@@ -0,0 +1,107 @@
+#/* @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                      = BdsLib

+  FILE_GUID                      = ddbf73a0-bb25-11df-8e4e-0002a5d5c51b

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BdsLib

+

+[Sources.common]

+  BdsFilePath.c

+  BdsAppLoader.c

+  BdsHelper.c

+  BdsLoadOption.c

+  BdsLinuxFdt.c

+

+[Sources.ARM]

+  Arm/BdsLinuxLoader.c

+  Arm/BdsLinuxAtag.c

+

+[Sources.AARCH64]

+  AArch64/BdsLinuxLoader.c

+  AArch64/BdsLinuxLoaderHelper.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  ArmSmcLib

+  BaseLib

+  DebugLib

+  DevicePathLib

+  HobLib

+  PcdLib

+  PerformanceLib

+  SerialPortLib

+  FdtLib

+  TimerLib

+  NetLib

+

+[LibraryClasses.AARCH64]

+  ArmGicLib

+

+[Guids]

+  gEfiFileInfoGuid

+  gArmMpCoreInfoGuid

+  gArmGlobalVariableGuid

+

+[Protocols]

+  gEfiBdsArchProtocolGuid

+  gEfiDevicePathProtocolGuid

+  gEfiDevicePathFromTextProtocolGuid

+  gEfiSimpleFileSystemProtocolGuid

+  gEfiFirmwareVolume2ProtocolGuid

+  gEfiLoadFileProtocolGuid

+  gEfiPxeBaseCodeProtocolGuid

+  gEfiDiskIoProtocolGuid

+  gEfiUsbIoProtocolGuid

+  gEfiLoadedImageProtocolGuid

+  gEfiSimpleNetworkProtocolGuid

+  gEfiDhcp4ServiceBindingProtocolGuid

+  gEfiDhcp4ProtocolGuid

+  gEfiMtftp4ServiceBindingProtocolGuid

+  gEfiMtftp4ProtocolGuid

+

+[FeaturePcd]

+  gArmTokenSpaceGuid.PcdArmLinuxSpinTable

+

+[Pcd]

+  gArmTokenSpaceGuid.PcdSystemMemoryBase

+  gArmTokenSpaceGuid.PcdSystemMemorySize

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmMachineType

+  gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset

+  gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment

+  gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset

+

+  gArmTokenSpaceGuid.PcdMaxTftpFileSize

+

+[FixedPcd.ARM]

+  gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset

+

+[Pcd.AARCH64]

+  gArmTokenSpaceGuid.PcdGicDistributorBase

+  gArmTokenSpaceGuid.PcdGicSgiIntId

+

+[Depex]

+  TRUE

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
new file mode 100644
index 0000000..e379552
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
@@ -0,0 +1,572 @@
+/** @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.

+*

+**/

+

+#include <Library/ArmSmcLib.h>

+#include <Library/PcdLib.h>

+#include <libfdt.h>

+

+#include "BdsInternal.h"

+#include "BdsLinuxLoader.h"

+

+#define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))

+#define PALIGN(p, a)    ((void *)(ALIGN((unsigned long)(p), (a))))

+#define GET_CELL(p)     (p += 4, *((const UINT32 *)(p-4)))

+

+STATIC

+UINTN

+cpu_to_fdtn (UINTN x) {

+  if (sizeof (UINTN) == sizeof (UINT32)) {

+    return cpu_to_fdt32 (x);

+  } else {

+    return cpu_to_fdt64 (x);

+  }

+}

+

+typedef struct {

+  UINTN   Base;

+  UINTN   Size;

+} FdtRegion;

+

+

+STATIC

+UINTN

+IsPrintableString (

+  IN CONST VOID* data,

+  IN UINTN len

+  )

+{

+  CONST CHAR8 *s = data;

+  CONST CHAR8 *ss;

+

+  // Zero length is not

+  if (len == 0) {

+    return 0;

+  }

+

+  // Must terminate with zero

+  if (s[len - 1] != '\0') {

+    return 0;

+  }

+

+  ss = s;

+  while (*s/* && isprint(*s)*/) {

+    s++;

+  }

+

+  // Not zero, or not done yet

+  if (*s != '\0' || (s + 1 - ss) < len) {

+    return 0;

+  }

+

+  return 1;

+}

+

+STATIC

+VOID

+PrintData (

+  IN CONST CHAR8* data,

+  IN UINTN len

+  )

+{

+  UINTN i;

+  CONST CHAR8 *p = data;

+

+  // No data, don't print

+  if (len == 0)

+    return;

+

+  if (IsPrintableString (data, len)) {

+    Print(L" = \"%a\"", (const char *)data);

+  } else if ((len % 4) == 0) {

+    Print(L" = <");

+    for (i = 0; i < len; i += 4) {

+      Print(L"0x%08x%a", fdt32_to_cpu(GET_CELL(p)),i < (len - 4) ? " " : "");

+    }

+    Print(L">");

+  } else {

+    Print(L" = [");

+    for (i = 0; i < len; i++)

+      Print(L"%02x%a", *p++, i < len - 1 ? " " : "");

+    Print(L"]");

+  }

+}

+

+VOID

+DebugDumpFdt (

+  IN VOID*                FdtBlob

+  )

+{

+  struct fdt_header *bph;

+  UINT32 off_dt;

+  UINT32 off_str;

+  CONST CHAR8* p_struct;

+  CONST CHAR8* p_strings;

+  CONST CHAR8* p;

+  CONST CHAR8* s;

+  CONST CHAR8* t;

+  UINT32 tag;

+  UINTN sz;

+  UINTN depth;

+  UINTN shift;

+  UINT32 version;

+

+  {

+    // Can 'memreserve' be printed by below code?

+    INTN num = fdt_num_mem_rsv(FdtBlob);

+    INTN i, err;

+    UINT64 addr = 0,size = 0;

+

+    for (i = 0; i < num; i++) {

+      err = fdt_get_mem_rsv(FdtBlob, i, &addr, &size);

+      if (err) {

+        DEBUG((EFI_D_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i));

+      }

+      else {

+        Print(L"/memreserve/ \t0x%lx \t0x%lx;\n",addr,size);

+      }

+    }

+  }

+

+  depth = 0;

+  shift = 4;

+

+  bph = FdtBlob;

+  off_dt = fdt32_to_cpu(bph->off_dt_struct);

+  off_str = fdt32_to_cpu(bph->off_dt_strings);

+  p_struct = (CONST CHAR8*)FdtBlob + off_dt;

+  p_strings = (CONST CHAR8*)FdtBlob + off_str;

+  version = fdt32_to_cpu(bph->version);

+

+  p = p_struct;

+  while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {

+    if (tag == FDT_BEGIN_NODE) {

+      s = p;

+      p = PALIGN(p + AsciiStrLen (s) + 1, 4);

+

+      if (*s == '\0')

+              s = "/";

+

+      Print(L"%*s%a {\n", depth * shift, L" ", s);

+

+      depth++;

+      continue;

+    }

+

+    if (tag == FDT_END_NODE) {

+      depth--;

+

+      Print(L"%*s};\n", depth * shift, L" ");

+      continue;

+    }

+

+    if (tag == FDT_NOP) {

+      Print(L"%*s// [NOP]\n", depth * shift, L" ");

+      continue;

+    }

+

+    if (tag != FDT_PROP) {

+      Print(L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag);

+      break;

+    }

+    sz = fdt32_to_cpu(GET_CELL(p));

+    s = p_strings + fdt32_to_cpu(GET_CELL(p));

+    if (version < 16 && sz >= 8)

+            p = PALIGN(p, 8);

+    t = p;

+

+    p = PALIGN(p + sz, 4);

+

+    Print(L"%*s%a", depth * shift, L" ", s);

+    PrintData(t, sz);

+    Print(L";\n");

+  }

+}

+

+STATIC

+BOOLEAN

+IsLinuxReservedRegion (

+  IN EFI_MEMORY_TYPE MemoryType

+  )

+{

+  switch(MemoryType) {

+  case EfiRuntimeServicesCode:

+  case EfiRuntimeServicesData:

+  case EfiUnusableMemory:

+  case EfiACPIReclaimMemory:

+  case EfiACPIMemoryNVS:

+  case EfiReservedMemoryType:

+    return TRUE;

+  default:

+    return FALSE;

+  }

+}

+

+/**

+** Relocate the FDT blob to a more appropriate location for the Linux kernel.

+** This function will allocate memory for the relocated FDT blob.

+**

+** @retval EFI_SUCCESS on success.

+** @retval EFI_OUT_OF_RESOURCES or EFI_INVALID_PARAMETER on failure.

+*/

+STATIC

+EFI_STATUS

+RelocateFdt (

+  EFI_PHYSICAL_ADDRESS   OriginalFdt,

+  UINTN                  OriginalFdtSize,

+  EFI_PHYSICAL_ADDRESS   *RelocatedFdt,

+  UINTN                  *RelocatedFdtSize,

+  EFI_PHYSICAL_ADDRESS   *RelocatedFdtAlloc

+  )

+{

+  EFI_STATUS            Status;

+  INTN                  Error;

+  UINT64                FdtAlignment;

+

+  *RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;

+

+  // If FDT load address needs to be aligned, allocate more space.

+  FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment);

+  if (FdtAlignment != 0) {

+    *RelocatedFdtSize += FdtAlignment;

+  }

+

+  // Try below a watermark address.

+  Status = EFI_NOT_FOUND;

+  if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) {

+    *RelocatedFdt = LINUX_FDT_MAX_OFFSET;

+    Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData,

+                    EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", *RelocatedFdt, Status));

+    }

+  }

+

+  // Try anywhere there is available space.

+  if (EFI_ERROR (Status)) {

+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData,

+                    EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);

+    if (EFI_ERROR (Status)) {

+      ASSERT_EFI_ERROR (Status);

+      return EFI_OUT_OF_RESOURCES;

+    } else {

+      DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", *RelocatedFdt));

+    }

+  }

+

+  *RelocatedFdtAlloc = *RelocatedFdt;

+  if (FdtAlignment != 0) {

+    *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment);

+  }

+

+  // Load the Original FDT tree into the new region

+  Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt,

+            (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize);

+  if (Error) {

+    DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error)));

+    gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize));

+    return EFI_INVALID_PARAMETER;

+  }

+

+  DEBUG_CODE_BEGIN();

+    //DebugDumpFdt (fdt);

+  DEBUG_CODE_END();

+

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+PrepareFdt (

+  IN     CONST CHAR8*         CommandLineArguments,

+  IN     EFI_PHYSICAL_ADDRESS InitrdImage,

+  IN     UINTN                InitrdImageSize,

+  IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase,

+  IN OUT UINTN                *FdtBlobSize

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  NewFdtBlobBase;

+  EFI_PHYSICAL_ADDRESS  NewFdtBlobAllocation;

+  UINTN                 NewFdtBlobSize;

+  VOID*                 fdt;

+  INTN                  err;

+  INTN                  node;

+  INTN                  cpu_node;

+  INT32                 lenp;

+  CONST VOID*           BootArg;

+  CONST VOID*           Method;

+  EFI_PHYSICAL_ADDRESS  InitrdImageStart;

+  EFI_PHYSICAL_ADDRESS  InitrdImageEnd;

+  FdtRegion             Region;

+  UINTN                 Index;

+  CHAR8                 Name[10];

+  LIST_ENTRY            ResourceList;

+  BDS_SYSTEM_MEMORY_RESOURCE  *Resource;

+  ARM_PROCESSOR_TABLE   *ArmProcessorTable;

+  ARM_CORE_INFO         *ArmCoreInfoTable;

+  UINT32                MpId;

+  UINT32                ClusterId;

+  UINT32                CoreId;

+  UINT64                CpuReleaseAddr;

+  UINTN                 MemoryMapSize;

+  EFI_MEMORY_DESCRIPTOR *MemoryMap;

+  EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;

+  UINTN                 MapKey;

+  UINTN                 DescriptorSize;

+  UINT32                DescriptorVersion;

+  UINTN                 Pages;

+  UINTN                 OriginalFdtSize;

+  BOOLEAN               CpusNodeExist;

+  UINTN                 CoreMpId;

+

+  NewFdtBlobAllocation = 0;

+

+  //

+  // Sanity checks on the original FDT blob.

+  //

+  err = fdt_check_header ((VOID*)(UINTN)(*FdtBlobBase));

+  if (err != 0) {

+    Print (L"ERROR: Device Tree header not valid (err:%d)\n", err);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  // The original FDT blob might have been loaded partially.

+  // Check that it is not the case.

+  OriginalFdtSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));

+  if (OriginalFdtSize > *FdtBlobSize) {

+    Print (L"ERROR: Incomplete FDT. Only %d/%d bytes have been loaded.\n",

+           *FdtBlobSize, OriginalFdtSize);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Relocate the FDT to its final location.

+  //

+  Status = RelocateFdt (*FdtBlobBase, OriginalFdtSize,

+             &NewFdtBlobBase, &NewFdtBlobSize, &NewFdtBlobAllocation);

+  if (EFI_ERROR (Status)) {

+    goto FAIL_RELOCATE_FDT;

+  }

+

+  fdt = (VOID*)(UINTN)NewFdtBlobBase;

+

+  node = fdt_subnode_offset (fdt, 0, "chosen");

+  if (node < 0) {

+    // The 'chosen' node does not exist, create it

+    node = fdt_add_subnode(fdt, 0, "chosen");

+    if (node < 0) {

+      DEBUG((EFI_D_ERROR,"Error on finding 'chosen' node\n"));

+      Status = EFI_INVALID_PARAMETER;

+      goto FAIL_COMPLETE_FDT;

+    }

+  }

+

+  DEBUG_CODE_BEGIN();

+    BootArg = fdt_getprop(fdt, node, "bootargs", &lenp);

+    if (BootArg != NULL) {

+      DEBUG((EFI_D_ERROR,"BootArg: %a\n",BootArg));

+    }

+  DEBUG_CODE_END();

+

+  //

+  // Set Linux CmdLine

+  //

+  if ((CommandLineArguments != NULL) && (AsciiStrLen (CommandLineArguments) > 0)) {

+    err = fdt_setprop(fdt, node, "bootargs", CommandLineArguments, AsciiStrSize(CommandLineArguments));

+    if (err) {

+      DEBUG((EFI_D_ERROR,"Fail to set new 'bootarg' (err:%d)\n",err));

+    }

+  }

+

+  //

+  // Set Linux Initrd

+  //

+  if (InitrdImageSize != 0) {

+    InitrdImageStart = cpu_to_fdt64 (InitrdImage);

+    err = fdt_setprop(fdt, node, "linux,initrd-start", &InitrdImageStart, sizeof(EFI_PHYSICAL_ADDRESS));

+    if (err) {

+      DEBUG((EFI_D_ERROR,"Fail to set new 'linux,initrd-start' (err:%d)\n",err));

+    }

+    InitrdImageEnd = cpu_to_fdt64 (InitrdImage + InitrdImageSize);

+    err = fdt_setprop(fdt, node, "linux,initrd-end", &InitrdImageEnd, sizeof(EFI_PHYSICAL_ADDRESS));

+    if (err) {

+      DEBUG((EFI_D_ERROR,"Fail to set new 'linux,initrd-start' (err:%d)\n",err));

+    }

+  }

+

+  //

+  // Set Physical memory setup if does not exist

+  //

+  node = fdt_subnode_offset(fdt, 0, "memory");

+  if (node < 0) {

+    // The 'memory' node does not exist, create it

+    node = fdt_add_subnode(fdt, 0, "memory");

+    if (node >= 0) {

+      fdt_setprop_string(fdt, node, "name", "memory");

+      fdt_setprop_string(fdt, node, "device_type", "memory");

+

+      GetSystemMemoryResources (&ResourceList);

+      Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink;

+

+      Region.Base = cpu_to_fdtn ((UINTN)Resource->PhysicalStart);

+      Region.Size = cpu_to_fdtn ((UINTN)Resource->ResourceLength);

+

+      err = fdt_setprop(fdt, node, "reg", &Region, sizeof(Region));

+      if (err) {

+        DEBUG((EFI_D_ERROR,"Fail to set new 'memory region' (err:%d)\n",err));

+      }

+    }

+  }

+

+  //

+  // Add the memory regions reserved by the UEFI Firmware

+  //

+

+  // Retrieve the UEFI Memory Map

+  MemoryMap = NULL;

+  MemoryMapSize = 0;

+  Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive

+    // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.

+    Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;

+    MemoryMap = AllocatePages (Pages);

+    if (MemoryMap == NULL) {

+      Status = EFI_OUT_OF_RESOURCES;

+      goto FAIL_COMPLETE_FDT;

+    }

+    Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);

+  }

+

+  // Go through the list and add the reserved region to the Device Tree

+  if (!EFI_ERROR(Status)) {

+    MemoryMapPtr = MemoryMap;

+    for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {

+      if (IsLinuxReservedRegion ((EFI_MEMORY_TYPE)MemoryMapPtr->Type)) {

+        DEBUG((DEBUG_VERBOSE, "Reserved region of type %d [0x%lX, 0x%lX]\n",

+            MemoryMapPtr->Type,

+            (UINTN)MemoryMapPtr->PhysicalStart,

+            (UINTN)(MemoryMapPtr->PhysicalStart + MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE)));

+        err = fdt_add_mem_rsv(fdt, MemoryMapPtr->PhysicalStart, MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE);

+        if (err != 0) {

+          Print(L"Warning: Fail to add 'memreserve' (err:%d)\n", err);

+        }

+      }

+      MemoryMapPtr = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + DescriptorSize);

+    }

+  }

+

+  //

+  // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms.

+  //

+  // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file

+  // in the kernel documentation:

+  // Documentation/devicetree/bindings/arm/cpus.txt

+  //

+  for (Index=0; Index < gST->NumberOfTableEntries; Index++) {

+    // Check for correct GUID type

+    if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {

+      MpId = ArmReadMpidr ();

+      ClusterId = GET_CLUSTER_ID(MpId);

+      CoreId    = GET_CORE_ID(MpId);

+

+      node = fdt_subnode_offset(fdt, 0, "cpus");

+      if (node < 0) {

+        // Create the /cpus node

+        node = fdt_add_subnode(fdt, 0, "cpus");

+        fdt_setprop_string(fdt, node, "name", "cpus");

+        fdt_setprop_cell (fdt, node, "#address-cells", sizeof (UINTN) / 4);

+        fdt_setprop_cell(fdt, node, "#size-cells", 0);

+        CpusNodeExist = FALSE;

+      } else {

+        CpusNodeExist = TRUE;

+      }

+

+      // Get pointer to ARM processor table

+      ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable;

+      ArmCoreInfoTable = ArmProcessorTable->ArmCpus;

+

+      for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) {

+        CoreMpId = (UINTN) GET_MPID (ArmCoreInfoTable[Index].ClusterId,

+                             ArmCoreInfoTable[Index].CoreId);

+        AsciiSPrint (Name, 10, "cpu@%x", CoreMpId);

+

+        // If the 'cpus' node did not exist then create all the 'cpu' nodes.

+        // In case 'cpus' node is provided in the original FDT then we do not add

+        // any 'cpu' node.

+        if (!CpusNodeExist) {

+          cpu_node = fdt_add_subnode (fdt, node, Name);

+          if (cpu_node < 0) {

+            DEBUG ((EFI_D_ERROR, "Error on creating '%s' node\n", Name));

+            Status = EFI_INVALID_PARAMETER;

+            goto FAIL_COMPLETE_FDT;

+          }

+

+          fdt_setprop_string (fdt, cpu_node, "device_type", "cpu");

+

+          CoreMpId = cpu_to_fdtn (CoreMpId);

+          fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId));

+        } else {

+          cpu_node = fdt_subnode_offset(fdt, node, Name);

+        }

+

+        if (cpu_node >= 0) {

+          Method = fdt_getprop (fdt, cpu_node, "enable-method", &lenp);

+          // We only care when 'enable-method' == 'spin-table'. If the enable-method is not defined

+          // or defined as 'psci' then we ignore its properties.

+          if ((Method != NULL) && (AsciiStrCmp ((CHAR8 *)Method, "spin-table") == 0)) {

+            // There are two cases;

+            //  - UEFI firmware parked the secondary cores and/or UEFI firmware is aware of the CPU

+            //    release addresses (PcdArmLinuxSpinTable == TRUE)

+            //  - the parking of the secondary cores has been managed before starting UEFI and/or UEFI

+            //    does not anything about the CPU release addresses - in this case we do nothing

+            if (FeaturePcdGet (PcdArmLinuxSpinTable)) {

+              CpuReleaseAddr = cpu_to_fdt64 (ArmCoreInfoTable[Index].MailboxSetAddress);

+              fdt_setprop (fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr));

+

+              // If it is not the primary core than the cpu should be disabled

+              if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) {

+                fdt_setprop_string(fdt, cpu_node, "status", "disabled");

+              }

+            }

+          }

+        }

+      }

+      break;

+    }

+  }

+

+  DEBUG_CODE_BEGIN();

+    //DebugDumpFdt (fdt);

+  DEBUG_CODE_END();

+

+  // If we succeeded to generate the new Device Tree then free the old Device Tree

+  gBS->FreePages (*FdtBlobBase, EFI_SIZE_TO_PAGES (*FdtBlobSize));

+

+  // Update the real size of the Device Tree

+  fdt_pack ((VOID*)(UINTN)(NewFdtBlobBase));

+

+  *FdtBlobBase = NewFdtBlobBase;

+  *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase));

+  return EFI_SUCCESS;

+

+FAIL_COMPLETE_FDT:

+  gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize));

+

+FAIL_RELOCATE_FDT:

+  *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));

+  // Return success even if we failed to update the FDT blob.

+  // The original one is still valid.

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxLoader.h b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxLoader.h
new file mode 100644
index 0000000..b78f606
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxLoader.h
@@ -0,0 +1,156 @@
+/** @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.

+*

+**/

+

+#ifndef __BDSLINUXLOADER_H

+#define __BDSLINUXLOADER_H

+

+#define LINUX_UIMAGE_SIGNATURE    0x56190527

+#define LINUX_KERNEL_MAX_OFFSET   (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxKernelMaxOffset))

+#define LINUX_ATAG_MAX_OFFSET     (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset))

+#define LINUX_FDT_MAX_OFFSET      (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxFdtMaxOffset))

+

+// Additional size that could be used for FDT entries added by the UEFI OS Loader

+// Estimation based on: EDID (300bytes) + bootargs (200bytes) + initrd region (20bytes)

+//                      + system memory region (20bytes) + mp_core entries (200 bytes)

+#define FDT_ADDITIONAL_ENTRIES_SIZE     0x300

+

+#define ARM_FDT_MACHINE_TYPE            0xFFFFFFFF

+

+typedef VOID (*LINUX_KERNEL)(UINT32 Zero, UINT32 Arch, UINTN ParametersBase);

+

+//

+// ATAG Definitions

+//

+

+#define ATAG_MAX_SIZE        0x3000

+

+/* ATAG : list of possible tags */

+#define ATAG_NONE            0x00000000

+#define ATAG_CORE            0x54410001

+#define ATAG_MEM             0x54410002

+#define ATAG_VIDEOTEXT       0x54410003

+#define ATAG_RAMDISK         0x54410004

+#define ATAG_INITRD2         0x54420005

+#define ATAG_SERIAL          0x54410006

+#define ATAG_REVISION        0x54410007

+#define ATAG_VIDEOLFB        0x54410008

+#define ATAG_CMDLINE         0x54410009

+#define ATAG_ARM_MP_CORE     0x5441000A

+

+#define next_tag_address(t)  ((LINUX_ATAG*)((UINT32)(t) + (((t)->header.size) << 2) ))

+#define tag_size(type)       ((UINT32)((sizeof(LINUX_ATAG_HEADER) + sizeof(type)) >> 2))

+

+typedef struct {

+  UINT32  size; /* length of tag in words including this header */

+  UINT32  type;  /* tag type */

+} LINUX_ATAG_HEADER;

+

+typedef struct {

+  UINT32  flags;

+  UINT32  pagesize;

+  UINT32  rootdev;

+} LINUX_ATAG_CORE;

+

+typedef struct {

+  UINT32  size;

+  UINTN  start;

+} LINUX_ATAG_MEM;

+

+typedef struct {

+  UINT8   x;

+  UINT8   y;

+  UINT16  video_page;

+  UINT8   video_mode;

+  UINT8   video_cols;

+  UINT16  video_ega_bx;

+  UINT8   video_lines;

+  UINT8   video_isvga;

+  UINT16  video_points;

+} LINUX_ATAG_VIDEOTEXT;

+

+typedef struct {

+  UINT32  flags;

+  UINT32  size;

+  UINTN  start;

+} LINUX_ATAG_RAMDISK;

+

+typedef struct {

+  UINT32  start;

+  UINT32  size;

+} LINUX_ATAG_INITRD2;

+

+typedef struct {

+  UINT32  low;

+  UINT32  high;

+} LINUX_ATAG_SERIALNR;

+

+typedef struct {

+  UINT32  rev;

+} LINUX_ATAG_REVISION;

+

+typedef struct {

+  UINT16  lfb_width;

+  UINT16  lfb_height;

+  UINT16  lfb_depth;

+  UINT16  lfb_linelength;

+  UINT32  lfb_base;

+  UINT32  lfb_size;

+  UINT8   red_size;

+  UINT8   red_pos;

+  UINT8   green_size;

+  UINT8   green_pos;

+  UINT8   blue_size;

+  UINT8   blue_pos;

+  UINT8   rsvd_size;

+  UINT8   rsvd_pos;

+} LINUX_ATAG_VIDEOLFB;

+

+typedef struct {

+  CHAR8   cmdline[1];

+} LINUX_ATAG_CMDLINE;

+

+typedef struct {

+  LINUX_ATAG_HEADER header;

+  union {

+    LINUX_ATAG_CORE         core_tag;

+    LINUX_ATAG_MEM          mem_tag;

+    LINUX_ATAG_VIDEOTEXT    videotext_tag;

+    LINUX_ATAG_RAMDISK      ramdisk_tag;

+    LINUX_ATAG_INITRD2      initrd2_tag;

+    LINUX_ATAG_SERIALNR     serialnr_tag;

+    LINUX_ATAG_REVISION     revision_tag;

+    LINUX_ATAG_VIDEOLFB     videolfb_tag;

+    LINUX_ATAG_CMDLINE      cmdline_tag;

+  } body;

+} LINUX_ATAG;

+

+EFI_STATUS

+PrepareAtagList (

+  IN  CONST CHAR8*          CommandLineString,

+  IN  EFI_PHYSICAL_ADDRESS  InitrdImage,

+  IN  UINTN                 InitrdImageSize,

+  OUT EFI_PHYSICAL_ADDRESS  *AtagBase,

+  OUT UINT32                *AtagSize

+  );

+

+EFI_STATUS

+PrepareFdt (

+  IN     CONST CHAR8*         CommandLineArguments,

+  IN     EFI_PHYSICAL_ADDRESS InitrdImage,

+  IN     UINTN                InitrdImageSize,

+  IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase,

+  IN OUT UINTN                *FdtBlobSize

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLoadOption.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLoadOption.c
new file mode 100644
index 0000000..be5ed41
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLoadOption.c
@@ -0,0 +1,270 @@
+/** @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 "BdsInternal.h"

+

+EFI_STATUS

+BootOptionParseLoadOption (

+  IN     EFI_LOAD_OPTION EfiLoadOption,

+  IN     UINTN           EfiLoadOptionSize,

+  IN OUT BDS_LOAD_OPTION **BdsLoadOption

+  )

+{

+  BDS_LOAD_OPTION *LoadOption;

+  UINTN           DescriptionLength;

+

+  if (EfiLoadOption == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) {

+    return EFI_BAD_BUFFER_SIZE;

+  }

+

+  if (*BdsLoadOption == NULL) {

+    LoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));

+    if (LoadOption == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  } else {

+    LoadOption = *BdsLoadOption;

+  }

+

+  LoadOption->LoadOption     = EfiLoadOption;

+  LoadOption->LoadOptionSize = EfiLoadOptionSize;

+

+  LoadOption->Attributes         = *(UINT32*)EfiLoadOption;

+  LoadOption->FilePathListLength = *(UINT16*)(EfiLoadOption + sizeof(UINT32));

+  LoadOption->Description        = (CHAR16*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16));

+  DescriptionLength              = StrSize (LoadOption->Description);

+  LoadOption->FilePathList       = (EFI_DEVICE_PATH_PROTOCOL*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16) + DescriptionLength);

+

+  // If ((End of EfiLoadOptiony - Start of EfiLoadOption) == EfiLoadOptionSize) then No Optional Data

+  if ((UINTN)((UINTN)LoadOption->FilePathList + LoadOption->FilePathListLength - (UINTN)EfiLoadOption) == EfiLoadOptionSize) {

+    LoadOption->OptionalData     = NULL;

+    LoadOption->OptionalDataSize = 0;

+  } else {

+    LoadOption->OptionalData     = (VOID*)((UINTN)(LoadOption->FilePathList) + LoadOption->FilePathListLength);

+    LoadOption->OptionalDataSize = EfiLoadOptionSize - ((UINTN)LoadOption->OptionalData - (UINTN)EfiLoadOption);

+  }

+

+  if (*BdsLoadOption == NULL) {

+    *BdsLoadOption = LoadOption;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BootOptionFromLoadOptionVariable (

+  IN  CHAR16*           BootVariableName,

+  OUT BDS_LOAD_OPTION** BdsLoadOption

+  )

+{

+  EFI_STATUS            Status;

+  EFI_LOAD_OPTION       EfiLoadOption;

+  UINTN                 EfiLoadOptionSize;

+

+  Status = GetGlobalEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);

+  if (!EFI_ERROR(Status)) {

+    *BdsLoadOption = NULL;

+    Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, BdsLoadOption);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+BootOptionFromLoadOptionIndex (

+  IN  UINT16            LoadOptionIndex,

+  OUT BDS_LOAD_OPTION **BdsLoadOption

+  )

+{

+  CHAR16        BootVariableName[9];

+  EFI_STATUS    Status;

+

+  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex);

+

+  Status = BootOptionFromLoadOptionVariable (BootVariableName, BdsLoadOption);

+  if (!EFI_ERROR(Status)) {

+    (*BdsLoadOption)->LoadOptionIndex = LoadOptionIndex;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+BootOptionToLoadOptionVariable (

+  IN BDS_LOAD_OPTION*   BdsLoadOption

+  )

+{

+  EFI_STATUS                    Status;

+  UINTN                         DescriptionSize;

+  //UINT16                        FilePathListLength;

+  EFI_DEVICE_PATH_PROTOCOL*     DevicePathNode;

+  UINTN                         NodeLength;

+  UINT8*                        EfiLoadOptionPtr;

+  VOID*                         OldLoadOption;

+  CHAR16                        BootVariableName[9];

+  UINTN                         BootOrderSize;

+  UINT16*                       BootOrder;

+

+  // If we are overwriting an existent Boot Option then we have to free previously allocated memory

+  if (BdsLoadOption->LoadOptionSize > 0) {

+    OldLoadOption = BdsLoadOption->LoadOption;

+  } else {

+    OldLoadOption = NULL;

+

+    // If this function is called at the creation of the Boot Device entry (not at the update) the

+    // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry

+    BdsLoadOption->LoadOptionIndex = BootOptionAllocateBootIndex ();

+

+    //TODO: Add to the the Boot Entry List

+  }

+

+  DescriptionSize = StrSize(BdsLoadOption->Description);

+

+  // Ensure the FilePathListLength information is correct

+  ASSERT (GetDevicePathSize (BdsLoadOption->FilePathList) == BdsLoadOption->FilePathListLength);

+

+  // Allocate the memory for the EFI Load Option

+  BdsLoadOption->LoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + DescriptionSize + BdsLoadOption->FilePathListLength + BdsLoadOption->OptionalDataSize;

+

+  BdsLoadOption->LoadOption = (EFI_LOAD_OPTION)AllocateZeroPool (BdsLoadOption->LoadOptionSize);

+  if (BdsLoadOption->LoadOption == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  EfiLoadOptionPtr = BdsLoadOption->LoadOption;

+

+  //

+  // Populate the EFI Load Option and BDS Boot Option structures

+  //

+

+  // Attributes fields

+  *(UINT32*)EfiLoadOptionPtr = BdsLoadOption->Attributes;

+  EfiLoadOptionPtr += sizeof(UINT32);

+

+  // FilePath List fields

+  *(UINT16*)EfiLoadOptionPtr = BdsLoadOption->FilePathListLength;

+  EfiLoadOptionPtr += sizeof(UINT16);

+

+  // Boot description fields

+  CopyMem (EfiLoadOptionPtr, BdsLoadOption->Description, DescriptionSize);

+  EfiLoadOptionPtr += DescriptionSize;

+

+  // File path fields

+  DevicePathNode = BdsLoadOption->FilePathList;

+  while (!IsDevicePathEndType (DevicePathNode)) {

+    NodeLength = DevicePathNodeLength(DevicePathNode);

+    CopyMem (EfiLoadOptionPtr, DevicePathNode, NodeLength);

+    EfiLoadOptionPtr += NodeLength;

+    DevicePathNode = NextDevicePathNode (DevicePathNode);

+  }

+

+  // Set the End Device Path Type

+  SetDevicePathEndNode (EfiLoadOptionPtr);

+  EfiLoadOptionPtr += sizeof(EFI_DEVICE_PATH);

+

+  // Fill the Optional Data

+  if (BdsLoadOption->OptionalDataSize > 0) {

+    CopyMem (EfiLoadOptionPtr, BdsLoadOption->OptionalData, BdsLoadOption->OptionalDataSize);

+  }

+

+  // Case where the fields have been updated

+  if (OldLoadOption) {

+    // Now, the old data has been copied to the new allocated packed structure, we need to update the pointers of BdsLoadOption

+    BootOptionParseLoadOption (BdsLoadOption->LoadOption, BdsLoadOption->LoadOptionSize, &BdsLoadOption);

+    // Free the old packed structure

+    FreePool (OldLoadOption);

+  }

+

+  // Create/Update Boot#### environment variable

+  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);

+  Status = gRT->SetVariable (

+      BootVariableName,

+      &gEfiGlobalVariableGuid,

+      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+      BdsLoadOption->LoadOptionSize,

+      BdsLoadOption->LoadOption

+      );

+

+  // When it is a new entry we must add the entry to the BootOrder

+  if (OldLoadOption == NULL) {

+    // Add the new Boot Index to the list

+    Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+    if (!EFI_ERROR(Status)) {

+      BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder);

+      // Add the new index at the end

+      BootOrder[BootOrderSize / sizeof(UINT16)] = BdsLoadOption->LoadOptionIndex;

+      BootOrderSize += sizeof(UINT16);

+    } else {

+      // BootOrder does not exist. Create it

+      BootOrderSize = sizeof(UINT16);

+      BootOrder = &(BdsLoadOption->LoadOptionIndex);

+    }

+

+    // Update (or Create) the BootOrder environment variable

+    gRT->SetVariable (

+        L"BootOrder",

+        &gEfiGlobalVariableGuid,

+        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+        BootOrderSize,

+        BootOrder

+        );

+    DEBUG((EFI_D_ERROR,"Create %s\n",BootVariableName));

+

+    // Free memory allocated by GetGlobalEnvironmentVariable

+    if (!EFI_ERROR(Status)) {

+      FreePool (BootOrder);

+    }

+  } else {

+    DEBUG((EFI_D_ERROR,"Update %s\n",BootVariableName));

+  }

+

+  return EFI_SUCCESS;

+}

+

+UINT16

+BootOptionAllocateBootIndex (

+  VOID

+  )

+{

+  EFI_STATUS        Status;

+  UINTN             Index;

+  UINT32            BootIndex;

+  UINT16            *BootOrder;

+  UINTN             BootOrderSize;

+  BOOLEAN           Found;

+

+  // Get the Boot Option Order from the environment variable

+  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+  if (!EFI_ERROR(Status)) {

+    for (BootIndex = 0; BootIndex <= 0xFFFF; BootIndex++) {

+      Found = FALSE;

+      for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {

+        if (BootOrder[Index] == BootIndex) {

+          Found = TRUE;

+          break;

+        }

+      }

+      if (!Found) {

+        return BootIndex;

+      }

+    }

+    FreePool (BootOrder);

+  }

+  // Return the first index

+  return 0;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memcpy.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memcpy.S
new file mode 100644
index 0000000..66102da
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memcpy.S
@@ -0,0 +1,125 @@
+/*

+ * Copyright (c) 2011 - 2013, ARM Ltd

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in the

+ *    documentation and/or other materials provided with the distribution.

+ * 3. The name of the company may not be used to endorse or promote

+ *    products derived from this software without specific prior written

+ *    permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED

+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

+ * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED

+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR

+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+

+.text

+.align 2

+

+

+GCC_ASM_EXPORT(memcpy)

+

+

+// Taken from Newlib BSD implementation.

+ASM_PFX(memcpy):

+        // Copy dst to x6, so we can preserve return value.

+        mov     x6, x0

+

+        // NOTE: although size_t is unsigned, this code uses signed

+        // comparisons on x2 so relies on nb never having its top bit

+        // set. In practice this is not going to be a real problem.

+

+        // Require at least 64 bytes to be worth aligning.

+        cmp     x2, #64

+        blt     qwordcopy

+

+        // Compute offset to align destination to 16 bytes.

+        neg     x3, x0

+        and     x3, x3, 15

+

+        cbz     x3, blockcopy           // offset == 0 is likely

+

+        // We know there is at least 64 bytes to be done, so we

+        // do a 16 byte misaligned copy at first and then later do

+        // all 16-byte aligned copies.  Some bytes will be copied

+        // twice, but there's no harm in that since memcpy does not

+        // guarantee correctness on overlap.

+

+        sub     x2, x2, x3              // nb -= offset

+        ldp     x4, x5, [x1]

+        add     x1, x1, x3

+        stp     x4, x5, [x6]

+        add     x6, x6, x3

+

+        // The destination pointer is now qword (16 byte) aligned.

+        // (The src pointer might be.)

+

+blockcopy:

+        // Copy 64 bytes at a time.

+        subs    x2, x2, #64

+        blt     3f

+2:      subs    x2, x2, #64

+        ldp     x4, x5, [x1,#0]

+        ldp     x8, x9, [x1,#16]

+        ldp     x10,x11,[x1,#32]

+        ldp     x12,x13,[x1,#48]

+        add     x1, x1, #64

+        stp     x4, x5, [x6,#0]

+        stp     x8, x9, [x6,#16]

+        stp     x10,x11,[x6,#32]

+        stp     x12,x13,[x6,#48]

+        add     x6, x6, #64

+        bge     2b

+

+        // Unwind pre-decrement

+3:      add     x2, x2, #64

+

+qwordcopy:

+        // Copy 0-48 bytes, 16 bytes at a time.

+        subs    x2, x2, #16

+        blt     tailcopy

+2:      ldp     x4, x5, [x1],#16

+        subs    x2, x2, #16

+        stp     x4, x5, [x6],#16

+        bge     2b

+

+        // No need to unwind the pre-decrement, it would not change

+        // the low 4 bits of the count. But how likely is it for the

+        // byte count to be multiple of 16? Is it worth the overhead

+        // of testing for x2 == -16?

+

+tailcopy:

+        // Copy trailing 0-15 bytes.

+        tbz     x2, #3, 1f

+        ldr     x4, [x1],#8             // copy 8 bytes

+        str     x4, [x6],#8

+1:

+        tbz     x2, #2, 1f

+        ldr     w4, [x1],#4             // copy 4 bytes

+        str     w4, [x6],#4

+1:

+        tbz     x2, #1, 1f

+        ldrh    w4, [x1],#2             // copy 2 bytes

+        strh    w4, [x6],#2

+1:

+        tbz     x2, #0, return

+        ldrb    w4, [x1]                // copy 1 byte

+        strb    w4, [x6]

+

+return:

+        // This is the only return point of memcpy.

+        ret

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c
new file mode 100644
index 0000000..069c932
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c
@@ -0,0 +1,25 @@
+/** @file

+

+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Base.h>

+

+void *memset(void *Destination, int Value, int Count)

+{

+  CHAR8 *Ptr = Destination;

+

+  while (Count--)

+          *Ptr++ = Value;

+

+  return Destination;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h
new file mode 100644
index 0000000..78d3e21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h
@@ -0,0 +1,99 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+#include <Base.h>

+#include <Library/DebugLib.h>

+

+#define CHAR_BIT  8

+

+typedef union {

+    INT64   all;

+    struct {

+        UINT32 low;

+        INT32  high;

+    };

+} dwords;

+

+typedef union {

+    UINT64  all;

+    struct {

+        UINT32 low;

+        UINT32 high;

+    };

+} udwords;

+

+// __aeabi_ return values

+typedef struct {

+  UINT64  Quotent;

+  UINT64  Remainder;

+} ulldiv_t;

+

+typedef struct {

+  INT64   Quotent;

+  INT64   Remainder;

+} lldiv_t;

+

+typedef struct {

+  UINT32  Quotent;

+  UINT32  Remainder;

+} uidiv_return;

+

+#if __GNUC__

+  #define COUNT_LEADING_ZEROS(_a)   __builtin_clz((_a))

+  #define COUNT_TRAILING_ZEROS(_a)  __builtin_ctz((_a))

+#else

+#error COUNT_LEADING_ZEROS() and COUNT_TRAILING_ZEROS() macros not ported to your compiler

+#endif

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
new file mode 100644
index 0000000..74960b1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__ashldi3)

+

+ASM_PFX(__ashldi3):

+  cmp  r2, #31

+  bls  L2

+  cmp  r2, #63

+  subls  r2, r2, #32

+  movls  r2, r0, asl r2

+  movhi  r2, #0

+  mov  r1, r2

+  mov  r0, #0

+  bx  lr

+L2:

+  cmp  r2, #0

+  rsbne  r3, r2, #32

+  movne  r3, r0, lsr r3

+  movne  r0, r0, asl r2

+  orrne  r1, r3, r1, asl r2

+  bx  lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c
new file mode 100644
index 0000000..e13ea01
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c
@@ -0,0 +1,83 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+#include "Llvm_int_lib.h"

+

+// Returns: a << b

+

+// Precondition:  0 <= b < bits_in_dword

+

+INT64

+__ashldi3(INT64 a, INT32 b)

+{

+    const int bits_in_word = (int)(sizeof(INT32) * CHAR_BIT);

+    dwords input;

+    dwords result;

+    input.all = a;

+    if (b & bits_in_word)  // bits_in_word <= b < bits_in_dword

+    {

+        result.low = 0;

+        result.high = input.low << (b - bits_in_word);

+    }

+    else  // 0 <= b < bits_in_word

+    {

+        if (b == 0)

+            return a;

+        result.low  = input.low << b;

+        result.high = (input.high << b) | (input.low >> (bits_in_word - b));

+    }

+    return result.all;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
new file mode 100644
index 0000000..3cee2c1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__ashrdi3)

+

+ASM_PFX(__ashrdi3):

+  cmp  r2, #31

+  bls  L2

+  cmp  r2, #63

+  subls  r2, r2, #32

+  mov  ip, r1, asr #31

+  movls  r2, r1, asr r2

+  movhi  r2, ip

+  mov  r0, r2

+  mov  r1, ip

+  bx  lr

+L2:

+  cmp  r2, #0

+  rsbne  r3, r2, #32

+  movne  r3, r1, asl r3

+  movne  r1, r1, asr r2

+  orrne  r0, r3, r0, lsr r2

+  bx  lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c
new file mode 100644
index 0000000..1617543
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c
@@ -0,0 +1,84 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+#include "Llvm_int_lib.h"

+

+// Returns: arithmetic a >> b

+

+// Precondition:  0 <= b < bits_in_dword

+

+INT64

+__ashrdi3(INT64 a, INT32 b)

+{

+    const int bits_in_word = (int)(sizeof(INT32) * CHAR_BIT);

+    dwords input;

+    dwords result;

+    input.all = a;

+    if (b & bits_in_word)  // bits_in_word <= b < bits_in_dword

+    {

+        // result.high = input.high < 0 ? -1 : 0

+        result.high = input.high >> (bits_in_word - 1);

+        result.low = input.high >> (b - bits_in_word);

+    }

+    else  // 0 <= b < bits_in_word

+    {

+        if (b == 0)

+            return a;

+        result.high  = input.high >> b;

+        result.low = (input.high << (bits_in_word - b)) | (input.low >> b);

+    }

+    return result.all;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
new file mode 100644
index 0000000..4cef265
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__clzsi2)

+

+ASM_PFX(__clzsi2):

+  @ frame_needed = 1, uses_anonymous_args = 0

+  stmfd  sp!, {r7, lr}

+  add  r7, sp, #0

+  movs  r3, r0, lsr #16

+  movne  r3, #16

+  moveq  r3, #0

+  movne  r9, #0

+  moveq  r9, #16

+  mov  r3, r0, lsr r3

+  tst  r3, #65280

+  movne  r0, #8

+  moveq  r0, #0

+  movne  lr, #0

+  moveq  lr, #8

+  mov  r3, r3, lsr r0

+  tst  r3, #240

+  movne  r0, #4

+  moveq  r0, #0

+  movne  ip, #0

+  moveq  ip, #4

+  mov  r3, r3, lsr r0

+  tst  r3, #12

+  movne  r0, #2

+  moveq  r0, #0

+  movne  r1, #0

+  moveq  r1, #2

+  mov  r2, r3, lsr r0

+  add  r3, lr, r9

+  add  r0, r3, ip

+  add  r1, r0, r1

+  mov  r0, r2, lsr #1

+  eor  r0, r0, #1

+  ands  r0, r0, #1

+  mvnne  r0, #0

+  rsb  r3, r2, #2

+  and  r0, r0, r3

+  add  r0, r1, r0

+  ldmfd  sp!, {r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c
new file mode 100644
index 0000000..5c2a3ea
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c
@@ -0,0 +1,96 @@
+/** @file

+  Compiler intrinsic to return the number of leading zeros, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+// Returns: the number of leading 0-bits

+

+// Precondition: a != 0

+

+INT32

+__clzsi2(INT32 a)

+{

+    UINT32 x = (UINT32)a;

+    INT32 t = ((x & 0xFFFF0000) == 0) << 4;  // if (x is small) t = 16 else 0

+    x >>= 16 - t;      // x = [0 - 0xFFFF]

+    UINT32 r = t;       // r = [0, 16]

+    // return r + clz(x)

+    t = ((x & 0xFF00) == 0) << 3;

+    x >>= 8 - t;       // x = [0 - 0xFF]

+    r += t;            // r = [0, 8, 16, 24]

+    // return r + clz(x)

+    t = ((x & 0xF0) == 0) << 2;

+    x >>= 4 - t;       // x = [0 - 0xF]

+    r += t;            // r = [0, 4, 8, 12, 16, 20, 24, 28]

+    // return r + clz(x)

+    t = ((x & 0xC) == 0) << 1;

+    x >>= 2 - t;       // x = [0 - 3]

+    r += t;            // r = [0 - 30] and is even

+    // return r + clz(x)

+//     switch (x)

+//     {

+//     case 0:

+//         return r + 2;

+//     case 1:

+//         return r + 1;

+//     case 2:

+//     case 3:

+//         return r;

+//     }

+    return r + ((2 - x) & -((x & 2) == 0));

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
new file mode 100644
index 0000000..108072e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__ctzsi2)

+

+ASM_PFX(__ctzsi2):

+  uxth  r3, r0

+  cmp  r3, #0

+  moveq  ip, #16

+  movne  ip, #0

+  @ lr needed for prologue

+  mov  r0, r0, lsr ip

+  tst  r0, #255

+  movne  r3, #0

+  moveq  r3, #8

+  mov  r0, r0, lsr r3

+  tst  r0, #15

+  movne  r1, #0

+  moveq  r1, #4

+  add  r3, r3, ip

+  mov  r0, r0, lsr r1

+  tst  r0, #3

+  movne  r2, #0

+  moveq  r2, #2

+  add  r3, r3, r1

+  mov  r0, r0, lsr r2

+  and  r0, r0, #3

+  add  r2, r3, r2

+  eor  r3, r0, #1

+  mov  r0, r0, lsr #1

+  ands  r3, r3, #1

+  mvnne  r3, #0

+  rsb  r0, r0, #2

+  and  r0, r3, r0

+  add  r0, r2, r0

+  bx  lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c
new file mode 100644
index 0000000..12cad92
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c
@@ -0,0 +1,98 @@
+/** @file

+  Compiler intrinsic to return the number of trailing zeros, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+// Returns: the number of trailing 0-bits

+

+// Precondition: a != 0

+

+INT32

+__ctzsi2(INT32 a)

+{

+    UINT32 x = (UINT32)a;

+    INT32 t = ((x & 0x0000FFFF) == 0) << 4;  // if (x has no small bits) t = 16 else 0

+    x >>= t;           // x = [0 - 0xFFFF] + higher garbage bits

+    UINT32 r = t;       // r = [0, 16]

+    // return r + ctz(x)

+    t = ((x & 0x00FF) == 0) << 3;

+    x >>= t;           // x = [0 - 0xFF] + higher garbage bits

+    r += t;            // r = [0, 8, 16, 24]

+    // return r + ctz(x)

+    t = ((x & 0x0F) == 0) << 2;

+    x >>= t;           // x = [0 - 0xF] + higher garbage bits

+    r += t;            // r = [0, 4, 8, 12, 16, 20, 24, 28]

+    // return r + ctz(x)

+    t = ((x & 0x3) == 0) << 1;

+    x >>= t;

+    x &= 3;            // x = [0 - 3]

+    r += t;            // r = [0 - 30] and is even

+    // return r + ctz(x)

+//  The branch-less return statement below is equivalent

+//  to the following switch statement:

+//     switch (x)

+//     {

+//     case 0:

+//         return r + 2;

+//     case 2:

+//         return r + 1;

+//     case 1:

+//     case 3:

+//         return r;

+//     }

+    return r + ((2 - (x >> 1)) & -((x & 1) == 0));

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S
new file mode 100644
index 0000000..faf70db
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S
@@ -0,0 +1,153 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2011, ARM. 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+GCC_ASM_EXPORT(__aeabi_uidiv)

+GCC_ASM_EXPORT(__aeabi_uidivmod)

+GCC_ASM_EXPORT(__aeabi_idiv)

+GCC_ASM_EXPORT(__aeabi_idivmod)

+

+#    AREA  Math, CODE, READONLY

+

+#

+#UINT32

+#EFIAPI

+#__aeabi_uidivmode (

+#  IN UINT32  Dividen

+#  IN UINT32  Divisor

+#  );

+#

+

+ASM_PFX(__aeabi_uidiv):

+ASM_PFX(__aeabi_uidivmod):

+  rsbs    r12, r1, r0, LSR #4

+  mov     r2, #0

+  bcc     ASM_PFX(__arm_div4)

+  rsbs    r12, r1, r0, LSR #8

+  bcc     ASM_PFX(__arm_div8)

+  mov     r3, #0

+  b       ASM_PFX(__arm_div_large)

+

+#

+#INT32

+#EFIAPI

+#__aeabi_idivmode (

+#  IN INT32  Dividen

+#  IN INT32  Divisor

+#  );

+#

+ASM_PFX(__aeabi_idiv):

+ASM_PFX(__aeabi_idivmod):

+  orrs    r12, r0, r1

+  bmi     ASM_PFX(__arm_div_negative)

+  rsbs    r12, r1, r0, LSR #1

+  mov     r2, #0

+  bcc     ASM_PFX(__arm_div1)

+  rsbs    r12, r1, r0, LSR #4

+  bcc     ASM_PFX(__arm_div4)

+  rsbs    r12, r1, r0, LSR #8

+  bcc     ASM_PFX(__arm_div8)

+  mov     r3, #0

+  b       ASM_PFX(__arm_div_large)

+ASM_PFX(__arm_div8):

+  rsbs    r12, r1, r0, LSR #7

+  subcs   r0, r0, r1, LSL #7

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0,LSR #6

+  subcs   r0, r0, r1, LSL #6

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #5

+  subcs   r0, r0, r1, LSL #5

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #4

+  subcs   r0, r0, r1, LSL #4

+  adc     r2, r2, r2

+ASM_PFX(__arm_div4):

+  rsbs    r12, r1, r0, LSR #3

+  subcs   r0, r0, r1, LSL #3

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #2

+  subcs   r0, r0, r1, LSL #2

+  adcs    r2, r2, r2

+  rsbs    r12, r1, r0, LSR #1

+  subcs   r0, r0, r1, LSL #1

+  adc     r2, r2, r2

+ASM_PFX(__arm_div1):

+  subs    r1, r0, r1

+  movcc   r1, r0

+  adc     r0, r2, r2

+  bx      r14

+ASM_PFX(__arm_div_negative):

+  ands    r2, r1, #0x80000000

+  rsbmi   r1, r1, #0

+  eors    r3, r2, r0, ASR #32

+  rsbcs   r0, r0, #0

+  rsbs    r12, r1, r0, LSR #4

+  bcc     label1

+  rsbs    r12, r1, r0, LSR #8

+  bcc     label2

+ASM_PFX(__arm_div_large):

+  lsl     r1, r1, #6

+  rsbs    r12, r1, r0, LSR #8

+  orr     r2, r2, #0xfc000000

+  bcc     label2

+  lsl     r1, r1, #6

+  rsbs    r12, r1, r0, LSR #8

+  orr     r2, r2, #0x3f00000

+  bcc     label2

+  lsl     r1, r1, #6

+  rsbs    r12, r1, r0, LSR #8

+  orr     r2, r2, #0xfc000

+  orrcs   r2, r2, #0x3f00

+  lslcs   r1, r1, #6

+  rsbs    r12, r1, #0

+  bcs     ASM_PFX(__aeabi_idiv0)

+label3:

+  lsrcs   r1, r1, #6

+label2:

+  rsbs    r12, r1, r0, LSR #7

+  subcs   r0, r0, r1, LSL #7

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #6

+  subcs   r0, r0, r1, LSL #6

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #5

+  subcs   r0, r0, r1, LSL #5

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #4

+  subcs   r0, r0, r1, LSL #4

+  adc     r2, r2, r2

+label1:

+  rsbs    r12, r1, r0, LSR #3

+  subcs   r0, r0, r1, LSL #3

+  adc     r2, r2, r2

+  rsbs    r12, r1, r0, LSR #2

+  subcs   r0, r0, r1, LSL #2

+  adcs    r2, r2, r2

+  bcs     label3

+  rsbs    r12, r1, r0, LSR #1

+  subcs   r0, r0, r1, LSL #1

+  adc     r2, r2, r2

+  subs    r1, r0, r1

+  movcc   r1, r0

+  adc     r0, r2, r2

+  asrs    r3, r3, #31

+  rsbmi   r0, r0, #0

+  rsbcs   r1, r1, #0

+  bx      r14

+

+  @ What to do about division by zero?  For now, just return.

+ASM_PFX(__aeabi_idiv0):

+  bx      r14

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
new file mode 100644
index 0000000..b539e51
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
@@ -0,0 +1,155 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_uidiv

+    EXPORT  __aeabi_uidivmod

+    EXPORT  __aeabi_idiv

+    EXPORT  __aeabi_idivmod

+

+    AREA  Math, CODE, READONLY

+

+;

+;UINT32

+;EFIAPI

+;__aeabi_uidivmode (

+;  IN UINT32  Dividen

+;  IN UINT32  Divisor

+;  );

+;

+

+__aeabi_uidiv

+__aeabi_uidivmod

+    RSBS    r12, r1, r0, LSR #4

+    MOV     r2, #0

+    BCC     __arm_div4

+    RSBS    r12, r1, r0, LSR #8

+    BCC     __arm_div8

+    MOV     r3, #0

+    B       __arm_div_large

+

+;

+;INT32

+;EFIAPI

+;__aeabi_idivmode (

+;  IN INT32  Dividen

+;  IN INT32  Divisor

+;  );

+;

+__aeabi_idiv

+__aeabi_idivmod

+    ORRS    r12, r0, r1

+    BMI     __arm_div_negative

+    RSBS    r12, r1, r0, LSR #1

+    MOV     r2, #0

+    BCC     __arm_div1

+    RSBS    r12, r1, r0, LSR #4

+    BCC     __arm_div4

+    RSBS    r12, r1, r0, LSR #8

+    BCC     __arm_div8

+    MOV     r3, #0

+    B       __arm_div_large

+__arm_div8

+    RSBS    r12, r1, r0, LSR #7

+    SUBCS   r0, r0, r1, LSL #7

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0,LSR #6

+    SUBCS   r0, r0, r1, LSL #6

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #5

+    SUBCS   r0, r0, r1, LSL #5

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #4

+    SUBCS   r0, r0, r1, LSL #4

+    ADC     r2, r2, r2

+__arm_div4

+    RSBS    r12, r1, r0, LSR #3

+    SUBCS   r0, r0, r1, LSL #3

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #2

+    SUBCS   r0, r0, r1, LSL #2

+    ADCS    r2, r2, r2

+    RSBS    r12, r1, r0, LSR #1

+    SUBCS   r0, r0, r1, LSL #1

+    ADC     r2, r2, r2

+__arm_div1

+    SUBS    r1, r0, r1

+    MOVCC   r1, r0

+    ADC     r0, r2, r2

+    BX      r14

+__arm_div_negative

+    ANDS    r2, r1, #0x80000000

+    RSBMI   r1, r1, #0

+    EORS    r3, r2, r0, ASR #32

+    RSBCS   r0, r0, #0

+    RSBS    r12, r1, r0, LSR #4

+    BCC     label1

+    RSBS    r12, r1, r0, LSR #8

+    BCC     label2

+__arm_div_large

+    LSL     r1, r1, #6

+    RSBS    r12, r1, r0, LSR #8

+    ORR     r2, r2, #0xfc000000

+    BCC     label2

+    LSL     r1, r1, #6

+    RSBS    r12, r1, r0, LSR #8

+    ORR     r2, r2, #0x3f00000

+    BCC     label2

+    LSL     r1, r1, #6

+    RSBS    r12, r1, r0, LSR #8

+    ORR     r2, r2, #0xfc000

+    ORRCS   r2, r2, #0x3f00

+    LSLCS   r1, r1, #6

+    RSBS    r12, r1, #0

+    BCS     __aeabi_idiv0

+label3

+    LSRCS   r1, r1, #6

+label2

+    RSBS    r12, r1, r0, LSR #7

+    SUBCS   r0, r0, r1, LSL #7

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #6

+    SUBCS   r0, r0, r1, LSL #6

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #5

+    SUBCS   r0, r0, r1, LSL #5

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #4

+    SUBCS   r0, r0, r1, LSL #4

+    ADC     r2, r2, r2

+label1

+    RSBS    r12, r1, r0, LSR #3

+    SUBCS   r0, r0, r1, LSL #3

+    ADC     r2, r2, r2

+    RSBS    r12, r1, r0, LSR #2

+    SUBCS   r0, r0, r1, LSL #2

+    ADCS    r2, r2, r2

+    BCS     label3

+    RSBS    r12, r1, r0, LSR #1

+    SUBCS   r0, r0, r1, LSL #1

+    ADC     r2, r2, r2

+    SUBS    r1, r0, r1

+    MOVCC   r1, r0

+    ADC     r0, r2, r2

+    ASRS    r3, r3, #31

+    RSBMI   r0, r0, #0

+    RSBCS   r1, r1, #0

+    BX      r14

+

+    ; What to do about division by zero?  For now, just return.

+__aeabi_idiv0

+    BX      r14

+

+    END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
new file mode 100644
index 0000000..23c8e8f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__divdi3)

+

+ASM_PFX(__divdi3):

+  @ args = 0, pretend = 0, frame = 0

+  @ frame_needed = 1, uses_anonymous_args = 0

+  stmfd  sp!, {r4, r5, r7, lr}

+  mov  r4, r3, asr #31

+  add  r7, sp, #8

+  stmfd  sp!, {r10, r11}

+  mov  r10, r1, asr #31

+  sub  sp, sp, #8

+  mov  r11, r10

+  mov  r5, r4

+  eor  r0, r0, r10

+  eor  r1, r1, r10

+  eor  r2, r2, r4

+  eor  r3, r3, r4

+  subs  r2, r2, r4

+  sbc  r3, r3, r5

+  mov  ip, #0

+  subs  r0, r0, r10

+  sbc  r1, r1, r11

+  str  ip, [sp, #0]

+  bl  ASM_PFX(__udivmoddi4)

+  eor  r2, r10, r4

+  eor  r3, r10, r4

+  eor  r0, r0, r2

+  eor  r1, r1, r3

+  subs  r0, r0, r2

+  sbc  r1, r1, r3

+  sub  sp, r7, #16

+  ldmfd  sp!, {r10, r11}

+  ldmfd  sp!, {r4, r5, r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c
new file mode 100644
index 0000000..c7916b8
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c
@@ -0,0 +1,77 @@
+/** @file

+  Compiler intrinsic for 64-bit compare, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+UINT64 __udivmoddi4(UINT64 a, UINT64 b, UINT64* rem);

+

+// Returns: a / b

+

+INT64

+__divdi3(INT64 a, INT64 b)

+{

+    const int bits_in_dword_m1 = (int)(sizeof(INT64) * CHAR_BIT) - 1;

+    INT64 s_a = a >> bits_in_dword_m1;           // s_a = a < 0 ? -1 : 0

+    INT64 s_b = b >> bits_in_dword_m1;           // s_b = b < 0 ? -1 : 0

+    a = (a ^ s_a) - s_a;                         // negate if s_a == -1

+    b = (b ^ s_b) - s_b;                         // negate if s_b == -1

+    s_a ^= s_b;                                  // sign of quotient

+    return (__udivmoddi4(a, b, (UINT64*)0) ^ s_a) - s_a;  // negate if s_a == -1

+}

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
new file mode 100644
index 0000000..d585146
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__divsi3)

+

+ASM_PFX(__divsi3):

+  eor  r3, r0, r0, asr #31

+  eor  r2, r1, r1, asr #31

+  stmfd  sp!, {r4, r5, r7, lr}

+  mov  r5, r0, asr #31

+  add  r7, sp, #8

+  mov  r4, r1, asr #31

+  sub  r0, r3, r0, asr #31

+  sub  r1, r2, r1, asr #31

+  bl  ASM_PFX(__udivsi3)

+  eor  r1, r5, r4

+  eor  r0, r0, r1

+  rsb  r0, r1, r0

+  ldmfd  sp!, {r4, r5, r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c
new file mode 100644
index 0000000..24e43dd
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c
@@ -0,0 +1,78 @@
+/** @file

+  Compiler intrinsic for 32--bit unsigned division, ported from LLVM code.

+

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+UINT32 __udivsi3(UINT32 n, UINT32 d);

+

+// Returns: a / b

+

+INT32

+__divsi3(INT32 a, INT32 b)

+{

+    const int bits_in_word_m1 = (int)(sizeof(INT32) * CHAR_BIT) - 1;

+    INT32 s_a = a >> bits_in_word_m1;           // s_a = a < 0 ? -1 : 0

+    INT32 s_b = b >> bits_in_word_m1;           // s_b = b < 0 ? -1 : 0

+    a = (a ^ s_a) - s_a;                         // negate if s_a == -1

+    b = (b ^ s_b) - s_b;                         // negate if s_b == -1

+    s_a ^= s_b;                                  // sign of quotient

+    return (__udivsi3(a, b) ^ s_a) - s_a;        // negate if s_a == -1

+}

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm
new file mode 100644
index 0000000..feb267a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm
@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_lasr

+

+    AREA    Math, CODE, READONLY

+

+;

+;UINT32

+;EFIAPI

+;__aeabi_lasr (

+;  IN UINT32  Dividen

+;  IN UINT32  Divisor

+;  );

+;

+__aeabi_lasr

+    SUBS     r3,r2,#0x20

+    BPL      {pc} + 0x18  ; 0x1c

+    RSB      r3,r2,#0x20

+    LSR      r0,r0,r2

+    ORR      r0,r0,r1,LSL r3

+    ASR      r1,r1,r2

+    BX       lr

+    ASR      r0,r1,r3

+    ASR      r1,r1,#31

+    BX       lr

+

+    END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
new file mode 100755
index 0000000..e7a05de
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
@@ -0,0 +1,59 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__aeabi_ldivmod)

+

+//

+// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},

+//  the quotient in {r0, r1}, and the remainder in {r2, r3}.

+//

+//__value_in_regs lldiv_t

+//EFIAPI

+//__aeabi_ldivmod (

+//  IN UINT64  Dividen

+//  IN UINT64  Divisor

+//  )//

+//

+

+ASM_PFX(__aeabi_ldivmod):

+    push     {r4,lr}

+    asrs     r4,r1,#1

+    eor      r4,r4,r3,LSR #1

+    bpl      L_Test1

+    rsbs     r0,r0,#0

+    rsc      r1,r1,#0

+L_Test1:

+    tst      r3,r3

+    bpl      L_Test2

+    rsbs     r2,r2,#0

+    rsc      r3,r3,#0

+L_Test2:

+    bl       ASM_PFX(__aeabi_uldivmod)

+    tst      r4,#0x40000000

+    beq      L_Test3

+    rsbs     r0,r0,#0

+    rsc      r1,r1,#0

+L_Test3:

+    tst      r4,#0x80000000

+    beq      L_Exit

+    rsbs     r2,r2,#0

+    rsc      r3,r3,#0

+L_Exit:

+    pop      {r4,pc}

+

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
new file mode 100644
index 0000000..9c14e89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_ldivmod

+    EXTERN  __aeabi_uldivmod

+

+    AREA    Math, CODE, READONLY

+

+;

+;UINT32

+;EFIAPI

+;__aeabi_uidivmode (

+;  IN UINT32  Dividen

+;  IN UINT32  Divisor

+;  );

+;

+

+__aeabi_ldivmod

+    PUSH     {r4,lr}

+    ASRS     r4,r1,#1

+    EOR      r4,r4,r3,LSR #1

+    BPL      L_Test1

+    RSBS     r0,r0,#0

+    RSC      r1,r1,#0

+L_Test1

+    TST      r3,r3

+    BPL      L_Test2

+    RSBS     r2,r2,#0

+    RSC      r3,r3,#0

+L_Test2

+    BL       __aeabi_uldivmod  ;

+    TST      r4,#0x40000000

+    BEQ      L_Test3

+    RSBS     r0,r0,#0

+    RSC      r1,r1,#0

+L_Test3

+    TST      r4,#0x80000000

+    BEQ      L_Exit

+    RSBS     r2,r2,#0

+    RSC      r3,r3,#0

+L_Exit

+    POP      {r4,pc}

+

+    END

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
new file mode 100644
index 0000000..ba8ab1c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2013, ARM. 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.

+#

+#------------------------------------------------------------------------------

+

+

+.text

+.align 2

+GCC_ASM_EXPORT(__aeabi_llsl)

+

+#

+#VOID

+#EFIAPI

+#__aeabi_llsl (

+# IN  VOID    *Destination,

+# IN  VOID    *Source,

+# IN  UINT32  Size

+# );

+#

+ASM_PFX(__aeabi_llsl):

+    subs     r3,r2,#0x20

+    bpl      1f

+    rsb      r3,r2,#0x20

+    lsl      r1,r1,r2

+    orr      r1,r1,r0,lsr r3

+    lsl      r0,r0,r2

+    bx       lr

+1:

+    lsl      r1,r0,r3

+    mov      r0,#0

+    bx       lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm
new file mode 100644
index 0000000..f6fc208
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_llsl

+

+    AREA    Math, CODE, READONLY

+

+;

+;VOID

+;EFIAPI

+;__aeabi_llsl (

+; IN  VOID    *Destination,

+; IN  VOID    *Source,

+; IN  UINT32  Size

+; );

+;

+

+__aeabi_llsl

+    SUBS     r3,r2,#0x20

+    BPL      {pc} + 0x18  ; 0x1c

+    RSB      r3,r2,#0x20

+    LSL      r1,r1,r2

+    ORR      r1,r1,r0,LSR r3

+    LSL      r0,r0,r2

+    BX       lr

+    LSL      r1,r0,r3

+    MOV      r0,#0

+    BX       lr

+

+    END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
new file mode 100644
index 0000000..3d2c106
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2013, ARM. 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.

+#

+#------------------------------------------------------------------------------

+

+

+.text

+.align 2

+GCC_ASM_EXPORT(__aeabi_llsr)

+

+#

+#VOID

+#EFIAPI

+#__aeabi_llsr (

+# IN  VOID    *Destination,

+# IN  VOID    *Source,

+# IN  UINT32  Size

+# );

+#

+ASM_PFX(__aeabi_llsr):

+    subs     r3,r2,#0x20

+    bpl      1f

+    rsb      r3,r2,#0x20

+    lsr      r0,r0,r2

+    orr      r0,r0,r1,lsl r3

+    lsr      r1,r1,r2

+    bx       lr

+1:

+    lsr      r0,r1,r3

+    mov      r1,#0

+    bx       lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
new file mode 100644
index 0000000..829c871
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_llsr

+

+    AREA    Math, CODE, READONLY

+

+;

+;VOID

+;EFIAPI

+;__aeabi_llsr (

+; IN  VOID    *Destination,

+; IN  VOID    *Source,

+; IN  UINT32  Size

+; );

+;

+__aeabi_llsr

+    SUBS     r3,r2,#0x20

+    BPL      {pc} + 0x18  ; 0x1c

+    RSB      r3,r2,#0x20

+    LSR      r0,r0,r2

+    ORR      r0,r0,r1,LSL r3

+    LSR      r1,r1,r2

+    BX       lr

+    LSR      r0,r1,r3

+    MOV      r1,#0

+    BX       lr

+

+    END

+

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
new file mode 100644
index 0000000..a313320
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__lshrdi3)

+

+ASM_PFX(__lshrdi3):

+  cmp  r2, #31

+  bls  L2

+  cmp  r2, #63

+  subls  r2, r2, #32

+  movls  r2, r1, lsr r2

+  movhi  r2, #0

+  mov  r0, r2

+  mov  r1, #0

+  bx  lr

+L2:

+  cmp  r2, #0

+  rsbne  r3, r2, #32

+  movne  r3, r1, asl r3

+  movne  r1, r1, lsr r2

+  orrne  r0, r3, r0, lsr r2

+  bx  lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c
new file mode 100644
index 0000000..2175cd9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c
@@ -0,0 +1,83 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+#include "Llvm_int_lib.h"

+

+// Returns: logical a >> b

+

+// Precondition:  0 <= b < bits_in_dword

+

+INT64

+__lshrdi3(INT64 a, INT32 b)

+{

+    const int bits_in_word = (int)(sizeof(INT32) * CHAR_BIT);

+    udwords input;

+    udwords result;

+    input.all = a;

+    if (b & bits_in_word)  // bits_in_word <= b < bits_in_dword

+    {

+        result.high = 0;

+        result.low = input.high >> (b - bits_in_word);

+    }

+    else  // 0 <= b < bits_in_word

+    {

+        if (b == 0)

+            return a;

+        result.high  = input.high >> b;

+        result.low = (input.high << (bits_in_word - b)) | (input.low >> b);

+    }

+    return result.all;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S
new file mode 100644
index 0000000..b68ed8a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__aeabi_memcpy)

+  GCC_ASM_EXPORT(memcpy)

+

+ASM_PFX(__aeabi_memcpy):

+ASM_PFX(memcpy):

+  cmp     r2, #0

+  bxeq    lr

+  push    {lr}

+  mov     lr, r0

+L5:

+  ldrb  r3, [r1], #1  @ zero_extendqisi2

+  strb  r3, [lr], #1

+  subs r2, r2, #1

+  bne  L5

+  pop  {pc}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm
new file mode 100644
index 0000000..60556b1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm
@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_memcpy

+

+    AREA    Memcpy, CODE, READONLY

+

+;

+;VOID

+;EFIAPI

+;__aeabi_memcpy (

+; IN  VOID    *Destination,

+; IN  VOID    *Source,

+; IN  UINT32  Size

+; );

+;

+__aeabi_memcpy

+  cmp     r2, #0

+  bxeq    lr

+  push    {lr}

+  mov     lr, r0

+L5

+  ldrb  r3, [r1], #1

+  strb  r3, [lr], #1

+  subs r2, r2, #1

+  bne  L5

+  pop  {pc}

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm
new file mode 100644
index 0000000..ecaa86f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_memcpy4

+

+    AREA    Memcpy4, CODE, READONLY

+

+;

+;VOID

+;EFIAPI

+;__aeabi_memcpy (

+; IN  VOID    *Destination,

+; IN  VOID    *Source,

+; IN  UINT32  Size

+; );

+;

+__aeabi_memcpy4

+    stmdb   sp!, {r4, lr}

+    subs    r2, r2, #32     ; 0x20

+    bcc     memcpy4_label2

+memcpy4_label1

+    ldmcsia r1!, {r3, r4, ip, lr}

+    stmcsia r0!, {r3, r4, ip, lr}

+    ldmcsia r1!, {r3, r4, ip, lr}

+    stmcsia r0!, {r3, r4, ip, lr}

+    subcss  r2, r2, #32     ; 0x20

+    bcs     memcpy4_label1

+memcpy4_label2

+    movs    ip, r2, lsl #28

+    ldmcsia r1!, {r3, r4, ip, lr}

+    stmcsia r0!, {r3, r4, ip, lr}

+    ldmmiia r1!, {r3, r4}

+    stmmiia r0!, {r3, r4}

+    ldmia   sp!, {r4, lr}

+    movs    ip, r2, lsl #30

+    ldrcs   r3, [r1], #4

+    strcs   r3, [r0], #4

+    bxeq    lr

+

+_memcpy4_lastbytes_aligned

+    movs    r2, r2, lsl #31

+    ldrcsh  r3, [r1], #2

+    ldrmib  r2, [r1], #1

+    strcsh  r3, [r0], #2

+    strmib  r2, [r0], #1

+    bx      lr

+

+    END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
new file mode 100644
index 0000000..79f95b0
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
@@ -0,0 +1,48 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT (memmove)

+

+# VOID

+# EFIAPI

+# memmove (

+#  IN  VOID          *Destination,

+#  IN  CONST VOID    *Source,

+#  IN  UINT32        Size

+#  );

+ASM_PFX(memmove):

+  CMP     r2, #0

+  BXEQ    lr

+  CMP     r0, r1

+  BXEQ    lr

+  BHI     memmove_backward

+

+memmove_forward:

+  LDRB    r3, [r1], #1

+  STRB    r3, [r0], #1

+  SUBS    r2, r2, #1

+  BXEQ    lr

+  B       memmove_forward

+

+memmove_backward:

+  add     r0, r2

+  add     r1, r2

+memmove_backward_loop:

+  LDRB    r3, [r1, #-1]!

+  STRB    r3, [r0, #-1]!

+  SUBS    r2, r2, #1

+  BXEQ    lr

+  B       memmove_backward_loop

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.asm
new file mode 100755
index 0000000..2147e29
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.asm
@@ -0,0 +1,53 @@
+//------------------------------------------------------------------------------

+//

+// 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.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_memmove

+

+    AREA    Memmove, CODE, READONLY

+

+;

+;VOID

+;EFIAPI

+;__aeabi_memmove (

+; IN  VOID          *Destination,

+; IN  CONST VOID    *Source,

+; IN  UINT32        Size

+; );

+;

+__aeabi_memmove

+  CMP     r2, #0

+  BXEQ    lr

+  CMP     r0, r1

+  BXEQ    lr

+  BHI     memmove_backward

+

+memmove_forward

+  LDRB    r3, [r1], #1

+  STRB    r3, [r0], #1

+  SUBS    r2, r2, #1

+  BNE     memmove_forward

+  BX      lr

+

+memmove_backward

+  add     r0, r2

+  add     r1, r2

+memmove_backward_loop

+  LDRB    r3, [r1, #-1]!

+  STRB    r3, [r0, #-1]!

+  SUBS    r2, r2, #1

+  BNE     memmove_backward_loop

+  BX      lr

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S
new file mode 100644
index 0000000..0c7789e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT (memset)

+

+# VOID

+# EFIAPI

+# memset (

+#  IN  VOID    *Destination,

+#  IN  UINT32  Character,

+#  IN  UINT32  Size

+#  );

+ASM_PFX(memset):

+  cmp  r2, #0

+  bxeq lr

+  @ args = 0, pretend = 0, frame = 0

+  @ frame_needed = 1, uses_anonymous_args = 0

+L10:

+  strb  r1, [r0], #1

+  subs  r2, r2, #1

+  @ While size is not 0

+  bne  L10

+  bx   lr

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.asm
new file mode 100755
index 0000000..bae3c1f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.asm
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+// 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.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_memset

+    EXPORT  __aeabi_memclr

+    EXPORT  __aeabi_memclr4

+

+    AREA    Memset, CODE, READONLY

+

+; void __aeabi_memclr4(void *dest, size_t n);

+; void __aeabi_memclr(void *dest, size_t n);

+__aeabi_memclr

+__aeabi_memclr4

+  mov   r2, #0

+

+;

+;VOID

+;EFIAPI

+;__aeabi_memset (

+; IN  VOID    *Destination,

+; IN  UINT32  Size,

+; IN  UINT32  Character

+; );

+;

+__aeabi_memset

+  cmp  r1, #0

+  bxeq lr

+  ; args = 0, pretend = 0, frame = 0

+  ; frame_needed = 1, uses_anonymous_args = 0

+L10

+  strb  r2, [r0], #1

+  subs  r1, r1, #1

+  ; While size is not 0

+  bne  L10

+  bx   lr

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
new file mode 100644
index 0000000..7b618eb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__moddi3)

+

+ASM_PFX(__moddi3):

+  stmfd  sp!, {r4, r5, r7, lr}

+  mov  r4, r1, asr #31

+  add  r7, sp, #8

+  stmfd  sp!, {r10, r11}

+  mov  r10, r3, asr #31

+  sub  sp, sp, #16

+  mov  r5, r4

+  mov  r11, r10

+  eor  r0, r0, r4

+  eor  r1, r1, r4

+  eor  r2, r2, r10

+  eor  r3, r3, r10

+  add  ip, sp, #8

+  subs  r0, r0, r4

+  sbc  r1, r1, r5

+  subs  r2, r2, r10

+  sbc  r3, r3, r11

+  str  ip, [sp, #0]

+  bl  ASM_PFX(__udivmoddi4)

+  ldrd  r0, [sp, #8]

+  eor  r0, r0, r4

+  eor  r1, r1, r4

+  subs  r0, r0, r4

+  sbc  r1, r1, r5

+  sub  sp, r7, #16

+  ldmfd  sp!, {r10, r11}

+  ldmfd  sp!, {r4, r5, r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c
new file mode 100644
index 0000000..04562de
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c
@@ -0,0 +1,77 @@
+/** @file

+  Compiler intrinsic for 64-bit mod, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+UINT64 __udivmoddi4(UINT64 a, UINT64 b, UINT64* rem);

+

+// Returns: a % b

+

+INT64

+__moddi3(INT64 a, INT64 b)

+{

+    const int bits_in_dword_m1 = (int)(sizeof(INT64) * CHAR_BIT) - 1;

+    INT64 s = b >> bits_in_dword_m1;  // s = b < 0 ? -1 : 0

+    b = (b ^ s) - s;                   // negate if s == -1

+    s = a >> bits_in_dword_m1;         // s = a < 0 ? -1 : 0

+    a = (a ^ s) - s;                   // negate if s == -1

+    INT64 r;

+    __udivmoddi4(a, b, (UINT64*)&r);

+    return (r ^ s) - s;                // negate if s == -1

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
new file mode 100644
index 0000000..047501e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
@@ -0,0 +1,27 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__modsi3)

+

+ASM_PFX(__modsi3):

+  stmfd  sp!, {r4, r5, r7, lr}

+  add  r7, sp, #8

+  mov  r5, r0

+  mov  r4, r1

+  bl  ___divsi3

+  mul  r0, r4, r0

+  rsb  r0, r0, r5

+  ldmfd  sp!, {r4, r5, r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c
new file mode 100644
index 0000000..91ee6aa
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c
@@ -0,0 +1,70 @@
+/** @file

+  Compiler intrinsic for 32-bit mod, ported from LLVM code.

+

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+// Returns: a % b

+

+INT32

+__modsi3(INT32 a, INT32 b)

+{

+    return a - (a / b) * b;

+}

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
new file mode 100644
index 0000000..dff61ef
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__muldi3)

+

+ASM_PFX(__muldi3):

+  stmfd  sp!, {r4, r5, r6, r7, lr}

+  add  r7, sp, #12

+  stmfd  sp!, {r8, r10, r11}

+  ldr  r11, L4

+  mov  r4, r0, lsr #16

+  and  r8, r0, r11

+  and  ip, r2, r11

+  mul  lr, ip, r8

+  mul  ip, r4, ip

+  sub  sp, sp, #8

+  add  r10, ip, lr, lsr #16

+  and  ip, r10, r11

+  and  lr, lr, r11

+  mov  r6, r2, lsr #16

+  str  r4, [sp, #4]

+  add  r4, lr, ip, asl #16

+  mul  ip, r8, r6

+  mov  r5, r10, lsr #16

+  add  r10, ip, r4, lsr #16

+  and  ip, r10, r11

+  and  lr, r4, r11

+  add  r4, lr, ip, asl #16

+  mul  r0, r3, r0

+  add  ip, r5, r10, lsr #16

+  ldr  r5, [sp, #4]

+  mla  r0, r2, r1, r0

+  mla  r5, r6, r5, ip

+  mov  r10, r4

+  add  r11, r0, r5

+  mov  r1, r11

+  mov  r0, r4

+  sub  sp, r7, #24

+  ldmfd  sp!, {r8, r10, r11}

+  ldmfd  sp!, {r4, r5, r6, r7, pc}

+  .p2align 2

+L5:

+  .align 2

+L4:

+  .long  65535

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c
new file mode 100644
index 0000000..dbdda86
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c
@@ -0,0 +1,98 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+#include <Base.h>

+#include "Llvm_int_lib.h"

+

+

+// Returns: a * b

+

+static

+INT64

+__muldsi3(UINT32 a, UINT32 b)

+{

+    dwords r;

+    const int bits_in_word_2 = (int)(sizeof(INT32) * CHAR_BIT) / 2;

+    const UINT32 lower_mask = (UINT32)~0 >> bits_in_word_2;

+    r.low = (a & lower_mask) * (b & lower_mask);

+    UINT32 t = r.low >> bits_in_word_2;

+    r.low &= lower_mask;

+    t += (a >> bits_in_word_2) * (b & lower_mask);

+    r.low += (t & lower_mask) << bits_in_word_2;

+    r.high = t >> bits_in_word_2;

+    t = r.low >> bits_in_word_2;

+    r.low &= lower_mask;

+    t += (b >> bits_in_word_2) * (a & lower_mask);

+    r.low += (t & lower_mask) << bits_in_word_2;

+    r.high += t >> bits_in_word_2;

+    r.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);

+    return r.all;

+}

+

+// Returns: a * b

+

+INT64

+__muldi3(INT64 a, INT64 b)

+{

+    dwords x;

+    x.all = a;

+    dwords y;

+    y.all = b;

+    dwords r;

+    r.all = __muldsi3(x.low, y.low);

+    r.high += x.high * y.low + x.low * y.high;

+    return r.all;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
new file mode 100644
index 0000000..e653559
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+.text

+

+GCC_ASM_EXPORT(__ARM_ll_mullu)

+GCC_ASM_EXPORT(__aeabi_lmul)

+#

+#INT64

+#EFIAPI

+#__aeabi_lmul (

+#  IN INT64   Multiplicand

+#  IN INT32   Multiplier

+#  );

+#

+ASM_PFX(__ARM_ll_mullu):

+  mov     r3, #0

+# Make upper part of INT64 Multiplier 0 and use __aeabi_lmul

+

+#

+#INT64

+#EFIAPI

+#__aeabi_lmul (

+#  IN INT64   Multiplicand

+#  IN INT64   Multiplier

+#  );

+#

+ASM_PFX(__aeabi_lmul):

+  stmdb   sp!, {lr}

+  mov     lr, r0

+  umull   r0, ip, r2, lr

+  mla     r1, r2, r1, ip

+  mla     r1, r3, lr, r1

+  ldmia   sp!, {pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm
new file mode 100644
index 0000000..3451c2c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+  EXPORT  __ARM_ll_mullu

+  EXPORT  __aeabi_lmul

+

+  AREA  Math, CODE, READONLY

+

+;

+;INT64

+;EFIAPI

+;__aeabi_lmul (

+;  IN INT64   Multiplicand

+;  IN INT32   Multiplier

+;  );

+;

+__ARM_ll_mullu

+  mov     r3, #0

+// Make upper part of INT64 Multiplier 0 and use __aeabi_lmul

+

+;

+;INT64

+;EFIAPI

+;__aeabi_lmul (

+;  IN INT64   Multiplicand

+;  IN INT64   Multiplier

+;  );

+;

+__aeabi_lmul

+  stmdb   sp!, {lr}

+  mov     lr, r0

+  umull   r0, ip, r2, lr

+  mla     r1, r2, r1, ip

+  mla     r1, r3, lr, r1

+  ldmia   sp!, {pc}

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
new file mode 100755
index 0000000..1e0b524
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
@@ -0,0 +1,55 @@
+#------s------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+

+       .text

+       .align 2

+       GCC_ASM_EXPORT(__aeabi_ulcmp)

+

+ASM_PFX(__aeabi_ulcmp):

+       stmfd   sp!, {r4, r5, r8}

+       cmp     r3, r1

+       mov     r8, r0

+       mov     r9, r1

+       mov     r4, r2

+       mov     r5, r3

+       bls     L16

+L2:

+       mvn     r0, #0

+L1:

+       ldmfd   sp!, {r4, r5, r8}

+       bx      lr

+L16:

+       beq     L17

+L4:

+       cmp     r9, r5

+       bhi     L7

+       beq     L18

+       cmp     r8, r4

+L14:

+       cmpeq   r9, r5

+       moveq   r0, #0

+       beq     L1

+       b       L1

+L18:

+       cmp     r8, r4

+       bls     L14

+L7:

+       mov     r0, #1

+       b       L1

+L17:

+       cmp     r2, r0

+       bhi     L2

+       b       L4

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm
new file mode 100644
index 0000000..e09c90c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm
@@ -0,0 +1,29 @@
+///------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+

+    EXPORT  __ARM_switch8

+

+    AREA  ArmSwitch, CODE, READONLY

+

+__ARM_switch8

+  LDRB    r12,[lr,#-1]

+  CMP      r3,r12

+  LDRBCC  r3,[lr,r3]

+  LDRBCS  r3,[lr,r12]

+  ADD      r12,lr,r3,LSL #1

+  BX      r12

+

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
new file mode 100644
index 0000000..7f41353
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
@@ -0,0 +1,31 @@
+#/** @file

+#  Compiler intrinsic for ARM compiler

+#

+#  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.;

+#

+#**/

+#

+

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(__switch16)

+

+ASM_PFX(__switch16):

+    ldrh      ip, [lr, #-1]

+    cmp       r0, ip

+    add       r0, lr, r0, lsl #1

+    ldrccsh   r0, [r0, #1]

+    add       ip, lr, ip, lsl #1

+    ldrcssh   r0, [ip, #1]

+    add       ip, lr, r0, lsl #1

+    bx        ip

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
new file mode 100644
index 0000000..8675a4a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
@@ -0,0 +1,30 @@
+#/** @file

+#  Compiler intrinsic for ARM compiler

+#

+#  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.;

+#

+#**/

+#

+

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(__switch32)

+

+ASM_PFX(__switch32):

+    ldr     ip, [lr, #-1]

+    cmp     r0, ip

+    add     r0, lr, r0, lsl #2

+    ldrcc   r0, [r0, #3]

+    add     ip, lr, ip, lsl #2

+    ldrcs   r0, [ip, #3]

+    add     ip, lr, r0

+    bx      ip

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
new file mode 100644
index 0000000..27edccb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
@@ -0,0 +1,28 @@
+#/** @file

+#  Compiler intrinsic for ARM compiler

+#

+#  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http)://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.;

+#

+#**/

+#

+

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(__switch8)

+

+ASM_PFX(__switch8):

+    ldrb      ip, [lr, #-1]

+    cmp       r0, ip

+    ldrccsb   r0, [lr, r0]

+    ldrcssb   r0, [lr, ip]

+    add       ip, lr, r0, lsl #1

+    bx        ip

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
new file mode 100644
index 0000000..39c4a7f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
@@ -0,0 +1,29 @@
+#/** @file

+#  Compiler intrinsic for ARM compiler

+#

+#  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution.  The full text of the license may be found at

+#  http)://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.;

+#

+#**/

+#

+

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(__switchu8)

+

+

+ASM_PFX(__switchu8):

+    ldrb      ip,[lr,#-1]

+    cmp       r0,ip

+    ldrccb    r0,[lr,r0]

+    ldrcsb    r0,[lr,ip]

+    add       ip,lr,r0,LSL #1

+    bx        ip

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
new file mode 100644
index 0000000..da57423
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__ucmpdi2)

+

+ASM_PFX(__ucmpdi2):

+  stmfd  sp!, {r4, r5, r8, lr}

+  cmp  r1, r3

+  mov  r8, r0

+  mov  r4, r2

+  mov  r5, r3

+  bcc  L2

+  bhi  L4

+  cmp  r0, r2

+  bcc  L2

+  movls  r0, #1

+  bls  L8

+  b  L4

+L2:

+  mov  r0, #0

+  b  L8

+L4:

+  mov  r0, #2

+L8:

+  ldmfd  sp!, {r4, r5, r8, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c
new file mode 100644
index 0000000..aa03a3d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c
@@ -0,0 +1,82 @@
+/** @file

+  Compiler intrinsic for 64-bit compare, ported from LLVM code.

+

+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+

+// Returns:  if (a <  b) returns 0

+//           if (a == b) returns 1

+//           if (a >  b) returns 2

+

+UINT32

+__ucmpdi2(UINT64 a, UINT64 b)

+{

+    udwords x;

+    x.all = a;

+    udwords y;

+    y.all = b;

+    if (x.high < y.high)

+        return 0;

+    if (x.high > y.high)

+        return 2;

+    if (x.low < y.low)

+        return 0;

+    if (x.low > y.low)

+        return 2;

+    return 1;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
new file mode 100644
index 0000000..cbfb127
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
@@ -0,0 +1,27 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__udivdi3)

+

+ASM_PFX(__udivdi3):

+  stmfd  sp!, {r7, lr}

+  add  r7, sp, #0

+  sub  sp, sp, #8

+  mov  ip, #0

+  str  ip, [sp, #0]

+  bl  ASM_PFX(__udivmoddi4)

+  sub  sp, r7, #0

+  ldmfd  sp!, {r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c
new file mode 100644
index 0000000..fc383b4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c
@@ -0,0 +1,71 @@
+/** @file

+  Compiler intrinsic for 64-bit unisigned div, ported from LLVM code.

+

+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+UINT64 __udivmoddi4 (UINT64 a, UINT64 b, UINT64 *rem);

+

+// Returns: a / b

+

+UINT64

+__udivdi3(UINT64 a, UINT64 b)

+{

+    return __udivmoddi4(a, b, 0);

+}

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
new file mode 100644
index 0000000..4c0ef5a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
@@ -0,0 +1,242 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__udivmoddi4)

+

+ASM_PFX(__udivmoddi4):

+  stmfd  sp!, {r4, r5, r6, r7, lr}

+  add  r7, sp, #12

+  stmfd  sp!, {r10, r11}

+  sub  sp, sp, #20

+  stmia  sp, {r2-r3}

+  ldr  r6, [sp, #48]

+  orrs  r2, r2, r3

+  mov  r10, r0

+  mov  r11, r1

+  beq  L2

+  subs  ip, r1, #0

+  bne  L4

+  cmp  r3, #0

+  bne  L6

+  cmp  r6, #0

+  beq  L8

+  mov  r1, r2

+  bl  ASM_PFX(__umodsi3)

+  mov  r1, #0

+  stmia  r6, {r0-r1}

+L8:

+  ldr  r1, [sp, #0]

+  mov  r0, r10

+  b  L45

+L6:

+  cmp  r6, #0

+  movne  r1, #0

+  stmneia  r6, {r0-r1}

+  b  L2

+L4:

+  ldr  r1, [sp, #0]

+  cmp  r1, #0

+  bne  L12

+  ldr  r2, [sp, #4]

+  cmp  r2, #0

+  bne  L14

+  cmp  r6, #0

+  beq  L16

+  mov  r1, r2

+  mov  r0, r11

+  bl  ASM_PFX(__umodsi3)

+  mov  r1, #0

+  stmia  r6, {r0-r1}

+L16:

+  ldr  r1, [sp, #4]

+  mov  r0, r11

+L45:

+  bl  ASM_PFX(__udivsi3)

+L46:

+  mov  r10, r0

+  mov  r11, #0

+  b  L10

+L14:

+  subs  r1, r0, #0

+  bne  L18

+  cmp  r6, #0

+  beq  L16

+  ldr  r1, [sp, #4]

+  mov  r0, r11

+  bl  ASM_PFX(__umodsi3)

+  mov  r4, r10

+  mov  r5, r0

+  stmia  r6, {r4-r5}

+  b  L16

+L18:

+  sub  r3, r2, #1

+  tst  r2, r3

+  bne  L22

+  cmp  r6, #0

+  movne  r4, r0

+  andne  r5, ip, r3

+  stmneia  r6, {r4-r5}

+L24:

+  rsb  r3, r2, #0

+  and  r3, r2, r3

+  clz  r3, r3

+  rsb  r3, r3, #31

+  mov  r0, ip, lsr r3

+  b  L46

+L22:

+  clz  r2, r2

+  clz  r3, ip

+  rsb  r3, r3, r2

+  cmp  r3, #30

+  bhi  L48

+  rsb  r2, r3, #31

+  add  lr, r3, #1

+  mov  r3, r1, asl r2

+  str  r3, [sp, #12]

+  mov  r3, r1, lsr lr

+  ldr  r0, [sp, #0]

+  mov  r5, ip, lsr lr

+  orr  r4, r3, ip, asl r2

+  str  r0, [sp, #8]

+  b  L29

+L12:

+  ldr  r3, [sp, #4]

+  cmp  r3, #0

+  bne  L30

+  sub  r3, r1, #1

+  tst  r1, r3

+  bne  L32

+  cmp  r6, #0

+  andne  r3, r3, r0

+  movne  r2, r3

+  movne  r3, #0

+  stmneia  r6, {r2-r3}

+L34:

+  cmp  r1, #1

+  beq  L10

+  rsb  r3, r1, #0

+  and  r3, r1, r3

+  clz  r3, r3

+  rsb  r0, r3, #31

+  mov  r1, ip, lsr r0

+  rsb  r3, r0, #32

+  mov  r0, r10, lsr r0

+  orr  ip, r0, ip, asl r3

+  str  r1, [sp, #12]

+  str  ip, [sp, #8]

+  ldrd  r10, [sp, #8]

+  b  L10

+L32:

+  clz  r2, r1

+  clz  r3, ip

+  rsb  r3, r3, r2

+  rsb  r4, r3, #31

+  mov  r2, r0, asl r4

+  mvn  r1, r3

+  and  r2, r2, r1, asr #31

+  add  lr, r3, #33

+  str  r2, [sp, #8]

+  add  r2, r3, #1

+  mov  r3, r3, asr #31

+  and  r0, r3, r0, asl r1

+  mov  r3, r10, lsr r2

+  orr  r3, r3, ip, asl r4

+  and  r3, r3, r1, asr #31

+  orr  r0, r0, r3

+  mov  r3, ip, lsr lr

+  str  r0, [sp, #12]

+  mov  r0, r10, lsr lr

+  and  r5, r3, r2, asr #31

+  rsb  r3, lr, #31

+  mov  r3, r3, asr #31

+  orr  r0, r0, ip, asl r1

+  and  r3, r3, ip, lsr r2

+  and  r0, r0, r2, asr #31

+  orr  r4, r3, r0

+  b  L29

+L30:

+  clz  r2, r3

+  clz  r3, ip

+  rsb  r3, r3, r2

+  cmp  r3, #31

+  bls  L37

+L48:

+  cmp  r6, #0

+  stmneia  r6, {r10-r11}

+  b  L2

+L37:

+  rsb  r1, r3, #31

+  mov  r0, r0, asl r1

+  add  lr, r3, #1

+  mov  r2, #0

+  str  r0, [sp, #12]

+  mov  r0, r10, lsr lr

+  str  r2, [sp, #8]

+  sub  r2, r3, #31

+  and  r0, r0, r2, asr #31

+  mov  r3, ip, lsr lr

+  orr  r4, r0, ip, asl r1

+  and  r5, r3, r2, asr #31

+L29:

+  mov  ip, #0

+  mov  r10, ip

+  b  L40

+L41:

+  ldr  r1, [sp, #12]

+  ldr  r2, [sp, #8]

+  mov  r3, r4, lsr #31

+  orr  r5, r3, r5, asl #1

+  mov  r3, r1, lsr #31

+  orr  r4, r3, r4, asl #1

+  mov  r3, r2, lsr #31

+  orr  r0, r3, r1, asl #1

+  orr  r1, ip, r2, asl #1

+  ldmia  sp, {r2-r3}

+  str  r0, [sp, #12]

+  subs  r2, r2, r4

+  sbc  r3, r3, r5

+  str  r1, [sp, #8]

+  subs  r0, r2, #1

+  sbc  r1, r3, #0

+  mov  r2, r1, asr #31

+  ldmia  sp, {r0-r1}

+  mov  r3, r2

+  and  ip, r2, #1

+  and  r3, r3, r1

+  and  r2, r2, r0

+  subs  r4, r4, r2

+  sbc  r5, r5, r3

+  add  r10, r10, #1

+L40:

+  cmp  r10, lr

+  bne  L41

+  ldrd  r0, [sp, #8]

+  adds  r0, r0, r0

+  adc  r1, r1, r1

+  cmp  r6, #0

+  orr  r10, r0, ip

+  mov  r11, r1

+  stmneia  r6, {r4-r5}

+  b  L10

+L2:

+  mov  r10, #0

+  mov  r11, #0

+L10:

+  mov  r0, r10

+  mov  r1, r11

+  sub  sp, r7, #20

+  ldmfd  sp!, {r10, r11}

+  ldmfd  sp!, {r4, r5, r6, r7, pc}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c
new file mode 100644
index 0000000..a268596
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c
@@ -0,0 +1,287 @@
+/** @file

+  Compiler intrinsic for 64-bit compare, ported from LLVM code.

+

+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+// Effects: if rem != 0, *rem = a % b

+// Returns: a / b

+

+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide

+

+UINT64

+__udivmoddi4 (UINT64 a, UINT64 b, UINT64* rem)

+{

+    const unsigned n_uword_bits = sizeof(UINT32) * CHAR_BIT;

+    const unsigned n_udword_bits = sizeof(UINT64) * CHAR_BIT;

+    udwords n;

+    n.all = a;

+    udwords d;

+    d.all = b;

+    udwords q;

+    udwords r;

+    unsigned sr;

+

+    if (b == 0) {

+//      ASSERT (FALSE);

+      return 0;

+    }

+

+    // special cases, X is unknown, K != 0

+    if (n.high == 0)

+    {

+        if (d.high == 0)

+        {

+            // 0 X

+            // ---

+            // 0 X

+            if (rem)

+                *rem = n.low % d.low;

+            return n.low / d.low;

+        }

+        // 0 X

+        // ---

+        // K X

+        if (rem)

+            *rem = n.low;

+        return 0;

+    }

+    // n.high != 0

+    if (d.low == 0)

+    {

+        if (d.high == 0)

+        {

+            // K X

+            // ---

+            // 0 0

+            if (rem)

+                *rem = n.high % d.low;

+            return n.high / d.low;

+        }

+        // d.high != 0

+        if (n.low == 0)

+        {

+            // K 0

+            // ---

+            // K 0

+            if (rem)

+            {

+                r.high = n.high % d.high;

+                r.low = 0;

+                *rem = r.all;

+            }

+            return n.high / d.high;

+        }

+        // K K

+        // ---

+        // K 0

+        if ((d.high & (d.high - 1)) == 0)     // if d is a power of 2

+        {

+            if (rem)

+            {

+                r.low = n.low;

+                r.high = n.high & (d.high - 1);

+                *rem = r.all;

+            }

+            return n.high >> COUNT_TRAILING_ZEROS(d.high);

+        }

+        // K K

+        // ---

+        // K 0

+        sr = COUNT_LEADING_ZEROS(d.high) - COUNT_LEADING_ZEROS(n.high);

+        // 0 <= sr <= n_uword_bits - 2 or sr large

+        if (sr > n_uword_bits - 2)

+        {

+           if (rem)

+                *rem = n.all;

+            return 0;

+        }

+        ++sr;

+        // 1 <= sr <= n_uword_bits - 1

+        // q.all = n.all << (n_udword_bits - sr);

+        q.low = 0;

+        q.high = n.low << (n_uword_bits - sr);

+        // r.all = n.all >> sr;

+        r.high = n.high >> sr;

+        r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);

+    }

+    else  // d.low != 0

+    {

+        if (d.high == 0)

+        {

+            // K X

+            // ---

+            // 0 K

+            if ((d.low & (d.low - 1)) == 0)     // if d is a power of 2

+            {

+                if (rem)

+                    *rem = n.low & (d.low - 1);

+                if (d.low == 1)

+                    return n.all;

+                unsigned sr = COUNT_TRAILING_ZEROS(d.low);

+                q.high = n.high >> sr;

+                q.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);

+                return q.all;

+            }

+            // K X

+            // ---

+            // 0 K

+            sr = 1 + n_uword_bits + COUNT_LEADING_ZEROS(d.low) - COUNT_LEADING_ZEROS(n.high);

+            // 2 <= sr <= n_udword_bits - 1

+            // q.all = n.all << (n_udword_bits - sr);

+            // r.all = n.all >> sr;

+            // if (sr == n_uword_bits)

+            // {

+            //     q.low = 0;

+            //     q.high = n.low;

+            //     r.high = 0;

+            //     r.low = n.high;

+            // }

+            // else if (sr < n_uword_bits)  // 2 <= sr <= n_uword_bits - 1

+            // {

+            //     q.low = 0;

+            //     q.high = n.low << (n_uword_bits - sr);

+            //     r.high = n.high >> sr;

+            //     r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);

+            // }

+            // else              // n_uword_bits + 1 <= sr <= n_udword_bits - 1

+            // {

+            //     q.low = n.low << (n_udword_bits - sr);

+            //     q.high = (n.high << (n_udword_bits - sr)) |

+            //              (n.low >> (sr - n_uword_bits));

+            //     r.high = 0;

+            //     r.low = n.high >> (sr - n_uword_bits);

+            // }

+            q.low =  (n.low << (n_udword_bits - sr)) &

+                     ((INT32)(n_uword_bits - sr) >> (n_uword_bits-1));

+            q.high = ((n.low << ( n_uword_bits - sr))                       &

+                     ((INT32)(sr - n_uword_bits - 1) >> (n_uword_bits-1))) |

+                     (((n.high << (n_udword_bits - sr))                     |

+                     (n.low >> (sr - n_uword_bits)))                        &

+                     ((INT32)(n_uword_bits - sr) >> (n_uword_bits-1)));

+            r.high = (n.high >> sr) &

+                     ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1));

+            r.low =  ((n.high >> (sr - n_uword_bits))                       &

+                     ((INT32)(n_uword_bits - sr - 1) >> (n_uword_bits-1))) |

+                     (((n.high << (n_uword_bits - sr))                      |

+                     (n.low >> sr))                                         &

+                     ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1)));

+        }

+        else

+        {

+            // K X

+            // ---

+            // K K

+            sr = COUNT_LEADING_ZEROS(d.high) - COUNT_LEADING_ZEROS(n.high);

+            // 0 <= sr <= n_uword_bits - 1 or sr large

+            if (sr > n_uword_bits - 1)

+            {

+               if (rem)

+                    *rem = n.all;

+                return 0;

+            }

+            ++sr;

+            // 1 <= sr <= n_uword_bits

+            // q.all = n.all << (n_udword_bits - sr);

+            q.low = 0;

+            q.high = n.low << (n_uword_bits - sr);

+            // r.all = n.all >> sr;

+            // if (sr < n_uword_bits)

+            // {

+            //     r.high = n.high >> sr;

+            //     r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);

+            // }

+            // else

+            // {

+            //     r.high = 0;

+            //     r.low = n.high;

+            // }

+            r.high = (n.high >> sr) &

+                     ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1));

+            r.low = (n.high << (n_uword_bits - sr)) |

+                    ((n.low >> sr)                  &

+                    ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1)));

+        }

+    }

+    // Not a special case

+    // q and r are initialized with:

+    // q.all = n.all << (n_udword_bits - sr);

+    // r.all = n.all >> sr;

+    // 1 <= sr <= n_udword_bits - 1

+    UINT32 carry = 0;

+    for (; sr > 0; --sr)

+    {

+        // r:q = ((r:q)  << 1) | carry

+        r.high = (r.high << 1) | (r.low  >> (n_uword_bits - 1));

+        r.low  = (r.low  << 1) | (q.high >> (n_uword_bits - 1));

+        q.high = (q.high << 1) | (q.low  >> (n_uword_bits - 1));

+        q.low  = (q.low  << 1) | carry;

+        // carry = 0;

+        // if (r.all >= d.all)

+        // {

+        //      r.all -= d.all;

+        //      carry = 1;

+        // }

+        const INT64 s = (INT64)(d.all - r.all - 1) >> (n_udword_bits - 1);

+        carry = s & 1;

+        r.all -= d.all & s;

+    }

+    q.all = (q.all << 1) | carry;

+    if (rem)

+        *rem = r.all;

+    return q.all;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
new file mode 100644
index 0000000..5e2d31c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__udivsi3)

+

+ASM_PFX(__udivsi3):

+  cmp  r1, #0

+  cmpne  r0, #0

+  stmfd  sp!, {r4, r5, r7, lr}

+  add  r7, sp, #8

+  beq  L2

+  clz  r2, r1

+  clz  r3, r0

+  rsb  r3, r3, r2

+  cmp  r3, #31

+  bhi  L2

+  ldmeqfd  sp!, {r4, r5, r7, pc}

+  add  r5, r3, #1

+  rsb  r3, r3, #31

+  mov  lr, #0

+  mov  r2, r0, asl r3

+  mov  ip, r0, lsr r5

+  mov  r4, lr

+  b  L8

+L9:

+  mov  r0, r2, lsr #31

+  orr  ip, r0, ip, asl #1

+  orr  r2, r3, lr

+  rsb  r3, ip, r1

+  sub  r3, r3, #1

+  and  r0, r1, r3, asr #31

+  mov  lr, r3, lsr #31

+  rsb  ip, r0, ip

+  add  r4, r4, #1

+L8:

+  cmp  r4, r5

+  mov  r3, r2, asl #1

+  bne  L9

+  orr  r0, r3, lr

+  ldmfd  sp!, {r4, r5, r7, pc}

+L2:

+  mov  r0, #0

+  ldmfd  sp!, {r4, r5, r7, pc}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c
new file mode 100644
index 0000000..8b9cb9f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c
@@ -0,0 +1,111 @@
+/** @file

+  Compiler intrinsic for 32-bit unsigned div, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+

+// Returns: n / d

+

+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide

+

+UINT32

+__udivsi3(UINT32 n, UINT32 d)

+{

+    const unsigned n_uword_bits = sizeof(UINT32) * CHAR_BIT;

+    UINT32 q;

+    UINT32 r;

+    unsigned sr;

+

+    // special cases

+    if (d == 0) {

+//        ASSERT (FALSE);

+        return 0; // ?!

+        }

+    if (n == 0)

+        return 0;

+

+    sr = COUNT_LEADING_ZEROS(d) - COUNT_LEADING_ZEROS(n);

+    // 0 <= sr <= n_uword_bits - 1 or sr large

+    if (sr > n_uword_bits - 1)  // d > r

+        return 0;

+    if (sr == n_uword_bits - 1)  // d == 1

+        return n;

+    ++sr;

+    // 1 <= sr <= n_uword_bits - 1

+    // Not a special case

+    q = n << (n_uword_bits - sr);

+    r = n >> sr;

+    UINT32 carry = 0;

+    for (; sr > 0; --sr)

+    {

+        // r:q = ((r:q)  << 1) | carry

+        r = (r << 1) | (q >> (n_uword_bits - 1));

+        q = (q << 1) | carry;

+        // carry = 0;

+        // if (r.all >= d.all)

+        // {

+        //      r.all -= d.all;

+        //      carry = 1;

+        // }

+        const INT32 s = (INT32)(d - r - 1) >> (n_uword_bits - 1);

+        carry = s & 1;

+        r -= d & s;

+    }

+    q = (q << 1) | carry;

+    return q;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
new file mode 100755
index 0000000..4481c6d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
@@ -0,0 +1,267 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__aeabi_uldivmod)

+

+//

+//UINT64

+//EFIAPI

+//__aeabi_uldivmod (

+//  IN  UINT64   Dividend

+//  IN  UINT64   Divisor

+//  )

+//

+ASM_PFX(__aeabi_uldivmod):

+  stmdb   sp!, {r4, r5, r6, lr}

+  mov     r4, r1

+  mov     r5, r0

+  mov     r6, #0  // 0x0

+  orrs    ip, r3, r2, lsr #31

+  bne     ASM_PFX(__aeabi_uldivmod_label1)

+  tst     r2, r2

+  beq     ASM_PFX(_ll_div0)

+  movs    ip, r2, lsr #15

+  addeq   r6, r6, #16     // 0x10

+  mov     ip, r2, lsl r6

+  movs    lr, ip, lsr #23

+  moveq   ip, ip, lsl #8

+  addeq   r6, r6, #8      // 0x8

+  movs    lr, ip, lsr #27

+  moveq   ip, ip, lsl #4

+  addeq   r6, r6, #4      // 0x4

+  movs    lr, ip, lsr #29

+  moveq   ip, ip, lsl #2

+  addeq   r6, r6, #2      // 0x2

+  movs    lr, ip, lsr #30

+  moveq   ip, ip, lsl #1

+  addeq   r6, r6, #1      // 0x1

+  b       ASM_PFX(_ll_udiv_small)

+ASM_PFX(__aeabi_uldivmod_label1):

+  tst     r3, #-2147483648        // 0x80000000

+  bne     ASM_PFX(__aeabi_uldivmod_label2)

+  movs    ip, r3, lsr #15

+  addeq   r6, r6, #16     // 0x10

+  mov     ip, r3, lsl r6

+  movs    lr, ip, lsr #23

+  moveq   ip, ip, lsl #8

+  addeq   r6, r6, #8      // 0x8

+  movs    lr, ip, lsr #27

+  moveq   ip, ip, lsl #4

+  addeq   r6, r6, #4      // 0x4

+  movs    lr, ip, lsr #29

+  moveq   ip, ip, lsl #2

+  addeq   r6, r6, #2      // 0x2

+  movs    lr, ip, lsr #30

+  addeq   r6, r6, #1      // 0x1

+  rsb     r3, r6, #32     // 0x20

+  moveq   ip, ip, lsl #1

+  orr     ip, ip, r2, lsr r3

+  mov     lr, r2, lsl r6

+  b       ASM_PFX(_ll_udiv_big)

+ASM_PFX(__aeabi_uldivmod_label2):

+  mov     ip, r3

+  mov     lr, r2

+  b       ASM_PFX(_ll_udiv_ginormous)

+

+ASM_PFX(_ll_udiv_small):

+  cmp     r4, ip, lsl #1

+  mov     r3, #0  // 0x0

+  subcs   r4, r4, ip, lsl #1

+  addcs   r3, r3, #2      // 0x2

+  cmp     r4, ip

+  subcs   r4, r4, ip

+  adcs    r3, r3, #0      // 0x0

+  add     r2, r6, #32     // 0x20

+  cmp     r2, #32 // 0x20

+  rsb     ip, ip, #0      // 0x0

+  bcc     ASM_PFX(_ll_udiv_small_label1)

+  orrs    r0, r4, r5, lsr #30

+  moveq   r4, r5

+  moveq   r5, #0  // 0x0

+  subeq   r2, r2, #32     // 0x20

+ASM_PFX(_ll_udiv_small_label1):

+  mov     r1, #0  // 0x0

+  cmp     r2, #16 // 0x10

+  bcc     ASM_PFX(_ll_udiv_small_label2)

+  movs    r0, r4, lsr #14

+  moveq   r4, r4, lsl #16

+  addeq   r1, r1, #16     // 0x10

+ASM_PFX(_ll_udiv_small_label2):

+  sub     lr, r2, r1

+  cmp     lr, #8  // 0x8

+  bcc     ASM_PFX(_ll_udiv_small_label3)

+  movs    r0, r4, lsr #22

+  moveq   r4, r4, lsl #8

+  addeq   r1, r1, #8      // 0x8

+ASM_PFX(_ll_udiv_small_label3):

+  rsb     r0, r1, #32     // 0x20

+  sub     r2, r2, r1

+  orr     r4, r4, r5, lsr r0

+  mov     r5, r5, lsl r1

+  cmp     r2, #1  // 0x1

+  bcc     ASM_PFX(_ll_udiv_small_label5)

+  sub     r2, r2, #1      // 0x1

+  and     r0, r2, #7      // 0x7

+  eor     r0, r0, #7      // 0x7

+  adds    r0, r0, r0, lsl #1

+  add     pc, pc, r0, lsl #2

+  nop                     // (mov r0,r0)

+ASM_PFX(_ll_udiv_small_label4):

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  sub     r2, r2, #8      // 0x8

+  tst     r2, r2

+  rsbcc   r4, ip, r4

+  bpl     ASM_PFX(_ll_udiv_small_label4)

+ASM_PFX(_ll_udiv_small_label5):

+  mov     r2, r4, lsr r6

+  bic     r4, r4, r2, lsl r6

+  adcs    r0, r5, r5

+  adc     r1, r4, r4

+  add     r1, r1, r3, lsl r6

+  mov     r3, #0  // 0x0

+  ldmia   sp!, {r4, r5, r6, pc}

+

+ASM_PFX(_ll_udiv_big):

+  subs    r0, r5, lr

+  mov     r3, #0  // 0x0

+  sbcs    r1, r4, ip

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r3, r3, #0      // 0x0

+  subs    r0, r5, lr

+  sbcs    r1, r4, ip

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r3, r3, #0      // 0x0

+  subs    r0, r5, lr

+  sbcs    r1, r4, ip

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r3, r3, #0      // 0x0

+  mov     r1, #0  // 0x0

+  rsbs    lr, lr, #0      // 0x0

+  rsc     ip, ip, #0      // 0x0

+  cmp     r6, #16 // 0x10

+  bcc     ASM_PFX(_ll_udiv_big_label1)

+  movs    r0, r4, lsr #14

+  moveq   r4, r4, lsl #16

+  addeq   r1, r1, #16     // 0x10

+ASM_PFX(_ll_udiv_big_label1):

+  sub     r2, r6, r1

+  cmp     r2, #8  // 0x8

+  bcc     ASM_PFX(_ll_udiv_big_label2)

+  movs    r0, r4, lsr #22

+  moveq   r4, r4, lsl #8

+  addeq   r1, r1, #8      // 0x8

+ASM_PFX(_ll_udiv_big_label2):

+  rsb     r0, r1, #32     // 0x20

+  sub     r2, r6, r1

+  orr     r4, r4, r5, lsr r0

+  mov     r5, r5, lsl r1

+  cmp     r2, #1  // 0x1

+  bcc     ASM_PFX(_ll_udiv_big_label4)

+  sub     r2, r2, #1      // 0x1

+  and     r0, r2, #3      // 0x3

+  rsb     r0, r0, #3      // 0x3

+  adds    r0, r0, r0, lsl #1

+  add     pc, pc, r0, lsl #3

+  nop                     // (mov r0,r0)

+ASM_PFX(_ll_udiv_big_label3):

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  movcs   r5, r0

+  movcs   r4, r1

+  sub     r2, r2, #4      // 0x4

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  tst     r2, r2

+  movcs   r5, r0

+  movcs   r4, r1

+  bpl     ASM_PFX(_ll_udiv_big_label3)

+ASM_PFX(_ll_udiv_big_label4):

+  mov     r1, #0  // 0x0

+  mov     r2, r5, lsr r6

+  bic     r5, r5, r2, lsl r6

+  adcs    r0, r5, r5

+  adc     r1, r1, #0      // 0x0

+  movs    lr, r3, lsl r6

+  mov     r3, r4, lsr r6

+  bic     r4, r4, r3, lsl r6

+  adc     r1, r1, #0      // 0x0

+  adds    r0, r0, lr

+  orr     r2, r2, r4, ror r6

+  adc     r1, r1, #0      // 0x0

+  ldmia   sp!, {r4, r5, r6, pc}

+

+ASM_PFX(_ll_udiv_ginormous):

+  subs    r2, r5, lr

+  mov     r1, #0  // 0x0

+  sbcs    r3, r4, ip

+  adc     r0, r1, r1

+  movcc   r2, r5

+  movcc   r3, r4

+  ldmia   sp!, {r4, r5, r6, pc}

+

+ASM_PFX(_ll_div0):

+  ldmia   sp!, {r4, r5, r6, lr}

+  mov     r0, #0  // 0x0

+  mov     r1, #0  // 0x0

+  b       ASM_PFX(__aeabi_ldiv0)

+

+ASM_PFX(__aeabi_ldiv0):

+  bx      r14

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
new file mode 100644
index 0000000..aed649b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
@@ -0,0 +1,268 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+

+    EXPORT  __aeabi_uldivmod

+

+    AREA  Uldivmod, CODE, READONLY

+

+;

+;UINT64

+;EFIAPI

+;__aeabi_uldivmod (

+;  IN  UINT64   Dividend

+;  IN  UINT64   Divisor

+;  )

+;

+__aeabi_uldivmod

+  stmdb   sp!, {r4, r5, r6, lr}

+  mov     r4, r1

+  mov     r5, r0

+  mov     r6, #0  ; 0x0

+  orrs    ip, r3, r2, lsr #31

+  bne     __aeabi_uldivmod_label1

+  tst     r2, r2

+  beq     _ll_div0

+  movs    ip, r2, lsr #15

+  addeq   r6, r6, #16     ; 0x10

+  mov     ip, r2, lsl r6

+  movs    lr, ip, lsr #23

+  moveq   ip, ip, lsl #8

+  addeq   r6, r6, #8      ; 0x8

+  movs    lr, ip, lsr #27

+  moveq   ip, ip, lsl #4

+  addeq   r6, r6, #4      ; 0x4

+  movs    lr, ip, lsr #29

+  moveq   ip, ip, lsl #2

+  addeq   r6, r6, #2      ; 0x2

+  movs    lr, ip, lsr #30

+  moveq   ip, ip, lsl #1

+  addeq   r6, r6, #1      ; 0x1

+  b       _ll_udiv_small

+__aeabi_uldivmod_label1

+  tst     r3, #-2147483648        ; 0x80000000

+  bne     __aeabi_uldivmod_label2

+  movs    ip, r3, lsr #15

+  addeq   r6, r6, #16     ; 0x10

+  mov     ip, r3, lsl r6

+  movs    lr, ip, lsr #23

+  moveq   ip, ip, lsl #8

+  addeq   r6, r6, #8      ; 0x8

+  movs    lr, ip, lsr #27

+  moveq   ip, ip, lsl #4

+  addeq   r6, r6, #4      ; 0x4

+  movs    lr, ip, lsr #29

+  moveq   ip, ip, lsl #2

+  addeq   r6, r6, #2      ; 0x2

+  movs    lr, ip, lsr #30

+  addeq   r6, r6, #1      ; 0x1

+  rsb     r3, r6, #32     ; 0x20

+  moveq   ip, ip, lsl #1

+  orr     ip, ip, r2, lsr r3

+  mov     lr, r2, lsl r6

+  b       _ll_udiv_big

+__aeabi_uldivmod_label2

+  mov     ip, r3

+  mov     lr, r2

+  b       _ll_udiv_ginormous

+

+_ll_udiv_small

+  cmp     r4, ip, lsl #1

+  mov     r3, #0  ; 0x0

+  subcs   r4, r4, ip, lsl #1

+  addcs   r3, r3, #2      ; 0x2

+  cmp     r4, ip

+  subcs   r4, r4, ip

+  adcs    r3, r3, #0      ; 0x0

+  add     r2, r6, #32     ; 0x20

+  cmp     r2, #32 ; 0x20

+  rsb     ip, ip, #0      ; 0x0

+  bcc     _ll_udiv_small_label1

+  orrs    r0, r4, r5, lsr #30

+  moveq   r4, r5

+  moveq   r5, #0  ; 0x0

+  subeq   r2, r2, #32     ; 0x20

+_ll_udiv_small_label1

+  mov     r1, #0  ; 0x0

+  cmp     r2, #16 ; 0x10

+  bcc     _ll_udiv_small_label2

+  movs    r0, r4, lsr #14

+  moveq   r4, r4, lsl #16

+  addeq   r1, r1, #16     ; 0x10

+_ll_udiv_small_label2

+  sub     lr, r2, r1

+  cmp     lr, #8  ; 0x8

+  bcc     _ll_udiv_small_label3

+  movs    r0, r4, lsr #22

+  moveq   r4, r4, lsl #8

+  addeq   r1, r1, #8      ; 0x8

+_ll_udiv_small_label3

+  rsb     r0, r1, #32     ; 0x20

+  sub     r2, r2, r1

+  orr     r4, r4, r5, lsr r0

+  mov     r5, r5, lsl r1

+  cmp     r2, #1  ; 0x1

+  bcc     _ll_udiv_small_label5

+  sub     r2, r2, #1      ; 0x1

+  and     r0, r2, #7      ; 0x7

+  eor     r0, r0, #7      ; 0x7

+  adds    r0, r0, r0, lsl #1

+  add     pc, pc, r0, lsl #2

+  nop                     ; (mov r0,r0)

+_ll_udiv_small_label4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  rsbcc   r4, ip, r4

+  adcs    r5, r5, r5

+  adcs    r4, ip, r4, lsl #1

+  sub     r2, r2, #8      ; 0x8

+  tst     r2, r2

+  rsbcc   r4, ip, r4

+  bpl     _ll_udiv_small_label4

+_ll_udiv_small_label5

+  mov     r2, r4, lsr r6

+  bic     r4, r4, r2, lsl r6

+  adcs    r0, r5, r5

+  adc     r1, r4, r4

+  add     r1, r1, r3, lsl r6

+  mov     r3, #0  ; 0x0

+  ldmia   sp!, {r4, r5, r6, pc}

+

+_ll_udiv_big

+  subs    r0, r5, lr

+  mov     r3, #0  ; 0x0

+  sbcs    r1, r4, ip

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r3, r3, #0      ; 0x0

+  subs    r0, r5, lr

+  sbcs    r1, r4, ip

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r3, r3, #0      ; 0x0

+  subs    r0, r5, lr

+  sbcs    r1, r4, ip

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r3, r3, #0      ; 0x0

+  mov     r1, #0  ; 0x0

+  rsbs    lr, lr, #0      ; 0x0

+  rsc     ip, ip, #0      ; 0x0

+  cmp     r6, #16 ; 0x10

+  bcc     _ll_udiv_big_label1

+  movs    r0, r4, lsr #14

+  moveq   r4, r4, lsl #16

+  addeq   r1, r1, #16     ; 0x10

+_ll_udiv_big_label1

+  sub     r2, r6, r1

+  cmp     r2, #8  ; 0x8

+  bcc     _ll_udiv_big_label2

+  movs    r0, r4, lsr #22

+  moveq   r4, r4, lsl #8

+  addeq   r1, r1, #8      ; 0x8

+_ll_udiv_big_label2

+  rsb     r0, r1, #32     ; 0x20

+  sub     r2, r6, r1

+  orr     r4, r4, r5, lsr r0

+  mov     r5, r5, lsl r1

+  cmp     r2, #1  ; 0x1

+  bcc     _ll_udiv_big_label4

+  sub     r2, r2, #1      ; 0x1

+  and     r0, r2, #3      ; 0x3

+  rsb     r0, r0, #3      ; 0x3

+  adds    r0, r0, r0, lsl #1

+  add     pc, pc, r0, lsl #3

+  nop                     ; (mov r0,r0)

+_ll_udiv_big_label3

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  movcs   r5, r0

+  movcs   r4, r1

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  movcs   r5, r0

+  movcs   r4, r1

+  sub     r2, r2, #4      ; 0x4

+  adcs    r5, r5, r5

+  adcs    r4, r4, r4

+  adcs    r0, lr, r5

+  adcs    r1, ip, r4

+  tst     r2, r2

+  movcs   r5, r0

+  movcs   r4, r1

+  bpl     _ll_udiv_big_label3

+_ll_udiv_big_label4

+  mov     r1, #0  ; 0x0

+  mov     r2, r5, lsr r6

+  bic     r5, r5, r2, lsl r6

+  adcs    r0, r5, r5

+  adc     r1, r1, #0      ; 0x0

+  movs    lr, r3, lsl r6

+  mov     r3, r4, lsr r6

+  bic     r4, r4, r3, lsl r6

+  adc     r1, r1, #0      ; 0x0

+  adds    r0, r0, lr

+  orr     r2, r2, r4, ror r6

+  adc     r1, r1, #0      ; 0x0

+  ldmia   sp!, {r4, r5, r6, pc}

+

+_ll_udiv_ginormous

+  subs    r2, r5, lr

+  mov     r1, #0  ; 0x0

+  sbcs    r3, r4, ip

+  adc     r0, r1, r1

+  movcc   r2, r5

+  movcc   r3, r4

+  ldmia   sp!, {r4, r5, r6, pc}

+

+_ll_div0

+  ldmia   sp!, {r4, r5, r6, lr}

+  mov     r0, #0  ; 0x0

+  mov     r1, #0  ; 0x0

+  b       __aeabi_ldiv0

+

+__aeabi_ldiv0

+  BX        r14

+

+  END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldivmod.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldivmod.c
new file mode 100755
index 0000000..8887938
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldivmod.c
@@ -0,0 +1,43 @@
+/** @file

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include "Llvm_int_lib.h"

+#include <Library/BaseLib.h>

+

+

+UINT32 __udivsi3(UINT32 n, UINT32 d);

+UINT32 __umodsi3(UINT32 a, UINT32 b);

+

+

+UINT64

+__aeabi_uidivmod(unsigned numerator, unsigned denominator)

+{

+  UINT64  Return;

+

+  Return = __udivsi3 (numerator, denominator);

+  Return |= LShiftU64 (__umodsi3 (numerator, denominator), 32);

+

+  return Return;

+}

+

+unsigned

+__aeabi_uidiv (unsigned n, unsigned d)

+{

+  return __udivsi3 (n, d);

+}

+

+

+

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
new file mode 100644
index 0000000..6b718a6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
@@ -0,0 +1,29 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__umoddi3)

+

+ASM_PFX(__umoddi3):

+  stmfd  sp!, {r7, lr}

+  add  r7, sp, #0

+  sub  sp, sp, #16

+  add  ip, sp, #8

+  str  ip, [sp, #0]

+  bl  ASM_PFX(__udivmoddi4)

+  ldrd  r0, [sp, #8]

+  sub  sp, r7, #0

+  ldmfd  sp!, {r7, pc}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c
new file mode 100644
index 0000000..2a2ec61
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c
@@ -0,0 +1,72 @@
+/** @file

+  Compiler intrinsic for 64-bit unsigned mod, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+UINT64 __udivmoddi4(UINT64 a, UINT64 b, UINT64* rem);

+

+// Returns: a % b

+

+UINT64

+__umoddi3(UINT64 a, UINT64 b)

+{

+    UINT64 r;

+    __udivmoddi4(a, b, &r);

+    return r;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
new file mode 100644
index 0000000..76c26be
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
@@ -0,0 +1,28 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+  .text

+  .align 2

+  GCC_ASM_EXPORT(__umodsi3)

+

+ASM_PFX(__umodsi3):

+  stmfd  sp!, {r4, r5, r7, lr}

+  add  r7, sp, #8

+  mov  r5, r0

+  mov  r4, r1

+  bl   ASM_PFX(__udivsi3)

+  mul  r0, r4, r0

+  rsb  r0, r0, r5

+  ldmfd  sp!, {r4, r5, r7, pc}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c
new file mode 100644
index 0000000..d0a5b76
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c
@@ -0,0 +1,68 @@
+/** @file

+  Compiler intrinsic for 32-bit unsigned mod, ported from LLVM code.

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+/**

+  University of Illinois/NCSA

+  Open Source License

+

+  Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.

+  All rights reserved.

+

+  Developed by:

+

+      LLVM Team

+

+      University of Illinois at Urbana-Champaign

+

+      http://llvm.org

+

+  Permission is hereby granted, free of charge, to any person obtaining a copy of

+  this software and associated documentation files (the "Software"), to deal with

+  the Software without restriction, including without limitation the rights to

+  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies

+  of the Software, and to permit persons to whom the Software is furnished to do

+  so, subject to the following conditions:

+

+      * Redistributions of source code must retain the above copyright notice,

+        this list of conditions and the following disclaimers.

+

+      * Redistributions in binary form must reproduce the above copyright notice,

+        this list of conditions and the following disclaimers in the

+        documentation and/or other materials provided with the distribution.

+

+      * Neither the names of the LLVM Team, University of Illinois at

+        Urbana-Champaign, nor the names of its contributors may be used to

+        endorse or promote products derived from this Software without specific

+        prior written permission.

+

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

+  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE

+  SOFTWARE.

+**/

+

+

+#include "Llvm_int_lib.h"

+

+

+// Returns: a % b

+

+UINT32

+__umodsi3(UINT32 a, UINT32 b)

+{

+    return a - (a / b) * b;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm
new file mode 100644
index 0000000..3d58965
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+

+    EXPORT  __aeabi_uread4

+    EXPORT  __aeabi_uread8

+

+    AREA  Uread4, CODE, READONLY

+

+;

+;UINT32

+;EFIAPI

+;__aeabi_uread4 (

+;  IN VOID   *Pointer

+;  );

+;

+__aeabi_uread4

+    ldrb    r1, [r0]

+    ldrb    r2, [r0, #1]

+    ldrb    r3, [r0, #2]

+    ldrb    r0, [r0, #3]

+    orr     r1, r1, r2, lsl #8

+    orr     r1, r1, r3, lsl #16

+    orr     r0, r1, r0, lsl #24

+    bx      lr

+

+;

+;UINT64

+;EFIAPI

+;__aeabi_uread8 (

+;  IN VOID   *Pointer

+;  );

+;

+__aeabi_uread8

+    mov     r3, r0

+

+    ldrb    r1, [r3]

+    ldrb    r2, [r3, #1]

+    orr     r1, r1, r2, lsl #8

+    ldrb    r2, [r3, #2]

+    orr     r1, r1, r2, lsl #16

+    ldrb    r0, [r3, #3]

+    orr     r0, r1, r0, lsl #24

+

+    ldrb    r1, [r3, #4]

+    ldrb    r2, [r3, #5]

+    orr     r1, r1, r2, lsl #8

+    ldrb    r2, [r3, #6]

+    orr     r1, r1, r2, lsl #16

+    ldrb    r2, [r3, #7]

+    orr     r1, r1, r2, lsl #24

+

+    bx      lr

+    END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm
new file mode 100644
index 0000000..85e1ba8
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+//

+// This program and the accompanying materials

+// are licensed and made available under the terms and conditions of the BSD License

+// which accompanies this distribution.  The full text of the license may be found at

+// http://opensource.org/licenses/bsd-license.php

+//

+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+//

+//------------------------------------------------------------------------------

+

+

+    EXPORT  __aeabi_uwrite4

+    EXPORT  __aeabi_uwrite8

+

+    AREA  Uwrite4, CODE, READONLY

+

+;

+;UINT32

+;EFIAPI

+;__aeabi_uwrite4 (

+;  IN UINT32 Data,

+;  IN VOID   *Pointer

+;  );

+;

+;

+__aeabi_uwrite4

+    mov     r2, r0, lsr #8

+    strb    r0, [r1]

+    strb    r2, [r1, #1]

+    mov     r2, r0, lsr #16

+    strb    r2, [r1, #2]

+    mov     r2, r0, lsr #24

+    strb    r2, [r1, #3]

+    bx      lr

+

+;

+;UINT64

+;EFIAPI

+;__aeabi_uwrite8 (

+;  IN UINT64 Data,    //r0-r1

+;  IN VOID   *Pointer //r2

+;  );

+;

+;

+__aeabi_uwrite8

+    mov     r3, r0, lsr #8

+    strb    r0, [r2]

+    strb    r3, [r2, #1]

+    mov     r3, r0, lsr #16

+    strb    r3, [r2, #2]

+    mov     r3, r0, lsr #24

+    strb    r3, [r2, #3]

+

+    mov     r3, r1, lsr #8

+    strb    r1, [r2, #4]

+    strb    r3, [r2, #5]

+    mov     r3, r1, lsr #16

+    strb    r3, [r2, #6]

+    mov     r3, r1, lsr #24

+    strb    r3, [r2, #7]

+    bx      lr

+

+    END

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
new file mode 100644
index 0000000..3487787
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -0,0 +1,107 @@
+#/** @file

+#  Base Library implementation.

+#

+#  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>

+#  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.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = CompilerIntrinsicsLib

+  FILE_GUID                      = 855274FA-3575-4C20-9709-C031DC5589FA

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = CompilerIntrinsicsLib

+

+[Sources.AARCH64]

+  AArch64/memcpy.S

+  AArch64/memset.c

+

+[Sources.ARM]

+  Arm/mullu.asm        | RVCT

+  Arm/switch.asm       | RVCT

+  Arm/llsr.asm         | RVCT

+  Arm/memcpy.asm       | RVCT

+  Arm/memcpy4.asm      | RVCT

+  Arm/memset.asm       | RVCT

+  Arm/memmove.asm      | RVCT

+  Arm/uread.asm        | RVCT

+  Arm/uwrite.asm       | RVCT

+  Arm/lasr.asm         | RVCT

+  Arm/llsl.asm         | RVCT

+  Arm/div.asm          | RVCT

+  Arm/uldiv.asm        | RVCT

+  Arm/ldivmod.asm      | RVCT

+

+

+#

+# Move .c to .s to work around LLVM issues

+#

+#  Arm/ashrdi3.c    | GCC

+#  Arm/ashldi3.c    | GCC

+#  Arm/divdi3.c     | GCC

+#  Arm/divsi3.c     | GCC

+#  Arm/lshrdi3.c    | GCC

+  Arm/ashrdi3.S    | GCC

+  Arm/ashldi3.S    | GCC

+  Arm/div.S        | GCC

+  Arm/divdi3.S     | GCC

+  Arm/divsi3.S     | GCC

+  Arm/lshrdi3.S    | GCC

+

+  Arm/memcpy.S     | GCC

+  Arm/memset.S     | GCC

+  Arm/memmove.S    | GCC

+

+#  Arm/modsi3.c     | GCC

+#  Arm/moddi3.c     | GCC

+#  Arm/muldi3.c     | GCC

+  Arm/modsi3.S     | GCC

+  Arm/moddi3.S     | GCC

+  Arm/muldi3.S     | GCC

+  Arm/mullu.S      | GCC

+

+#  Arm/udivsi3.c    | GCC

+#  Arm/umodsi3.c    | GCC

+#  Arm/udivdi3.c    | GCC

+#  Arm/umoddi3.c    | GCC

+#  Arm/udivmoddi4.c | GCC

+  Arm/udivsi3.S    | GCC

+  Arm/umodsi3.S    | GCC

+  Arm/udivdi3.S    | GCC

+  Arm/umoddi3.S    | GCC

+  Arm/udivmoddi4.S | GCC

+

+#  Arm/clzsi2.c     | GCC

+#  Arm/ctzsi2.c     | GCC

+#  Arm/ucmpdi2.c    | GCC

+  Arm/clzsi2.S     | GCC

+  Arm/ctzsi2.S     | GCC

+  Arm/ucmpdi2.S    | GCC

+  Arm/switch8.S    | GCC

+  Arm/switchu8.S   | GCC

+  Arm/switch16.S   | GCC

+  Arm/switch32.S   | GCC

+

+  Arm/sourcery.S   | GCC

+  Arm/uldiv.S      | GCC

+  Arm/ldivmod.S    | GCC

+

+  Arm/llsr.S       | GCC

+  Arm/llsl.S       | GCC

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/AArch64/DebugAgentException.S b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/AArch64/DebugAgentException.S
new file mode 100644
index 0000000..022e279
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/AArch64/DebugAgentException.S
@@ -0,0 +1,93 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+#------------------------------------------------------------------------------

+

+GCC_ASM_EXPORT(DebugAgentVectorTable)

+GCC_ASM_IMPORT(DefaultExceptionHandler)

+

+.text

+ASM_PFX(DebugAgentVectorTable):

+

+//

+// Current EL with SP0 : 0x0 - 0x180

+//

+.align 11

+ASM_PFX(SynchronousExceptionSP0):

+  b   ASM_PFX(SynchronousExceptionSP0)

+

+.align 7

+ASM_PFX(IrqSP0):

+  b   ASM_PFX(IrqSP0)

+

+.align 7

+ASM_PFX(FiqSP0):

+  b   ASM_PFX(FiqSP0)

+

+.align 7

+ASM_PFX(SErrorSP0):

+  b   ASM_PFX(SErrorSP0)

+

+//

+// Current EL with SPx: 0x200 - 0x380

+//

+.align 7

+ASM_PFX(SynchronousExceptionSPx):

+  b   ASM_PFX(SynchronousExceptionSPx)

+

+.align 7

+ASM_PFX(IrqSPx):

+  b   ASM_PFX(IrqSPx)

+

+.align 7

+ASM_PFX(FiqSPx):

+  b   ASM_PFX(FiqSPx)

+

+.align 7

+ASM_PFX(SErrorSPx):

+  b   ASM_PFX(SErrorSPx)

+

+/* Lower EL using AArch64 : 0x400 - 0x580 */

+.align 7

+ASM_PFX(SynchronousExceptionA64):

+  b   ASM_PFX(SynchronousExceptionA64)

+

+.align 7

+ASM_PFX(IrqA64):

+  b   ASM_PFX(IrqA64)

+

+.align 7

+ASM_PFX(FiqA64):

+  b   ASM_PFX(FiqA64)

+

+.align 7

+ASM_PFX(SErrorA64):

+  b   ASM_PFX(SErrorA64)

+

+//

+// Lower EL using AArch32 : 0x0 - 0x180

+//

+.align 7

+ASM_PFX(SynchronousExceptionA32):

+  b   ASM_PFX(SynchronousExceptionA32)

+

+.align 7

+ASM_PFX(IrqA32):

+  b   ASM_PFX(IrqA32)

+

+.align 7

+ASM_PFX(FiqA32):

+  b   ASM_PFX(FiqA32)

+

+.align 7

+ASM_PFX(SErrorA32):

+  b   ASM_PFX(SErrorA32)

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S
new file mode 100644
index 0000000..0566a89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S
@@ -0,0 +1,276 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# 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/PcdLib.h>

+

+/*

+

+This is the stack constructed by the exception handler (low address to high address)

+                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM

+  Reg   Offset

+  ===   ======

+  R0    0x00    # stmfd     SP!,{R0-R12}

+  R1    0x04

+  R2    0x08

+  R3    0x0c

+  R4    0x10

+  R5    0x14

+  R6    0x18

+  R7    0x1c

+  R8    0x20

+  R9    0x24

+  R10   0x28

+  R11   0x2c

+  R12   0x30

+  SP    0x34    # reserved via adding 0x20 (32) to the SP

+  LR    0x38

+  PC    0x3c

+  CPSR  0x40

+  DFSR  0x44

+  DFAR  0x48

+  IFSR  0x4c

+  IFAR  0x50

+

+  LR    0x54    # SVC Link register (we need to restore it)

+

+  LR    0x58    # pushed by srsfd

+  CPSR  0x5c

+

+ */

+

+GCC_ASM_EXPORT(DebugAgentVectorTable)

+GCC_ASM_IMPORT(DefaultExceptionHandler)

+

+.text

+#if !defined(__APPLE__)

+.fpu neon    @ makes vpush/vpop assemble

+#endif

+.align 5

+

+

+//

+// This code gets copied to the ARM vector table

+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied

+//

+ASM_PFX(DebugAgentVectorTable):

+  b ASM_PFX(ResetEntry)

+  b ASM_PFX(UndefinedInstructionEntry)

+  b ASM_PFX(SoftwareInterruptEntry)

+  b ASM_PFX(PrefetchAbortEntry)

+  b ASM_PFX(DataAbortEntry)

+  b ASM_PFX(ReservedExceptionEntry)

+  b ASM_PFX(IrqEntry)

+  b ASM_PFX(FiqEntry)

+

+ASM_PFX(ResetEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+                                      @ We are already in SVC mode

+

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#0                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(UndefinedInstructionEntry):

+  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#1                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(SoftwareInterruptEntry):

+  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry

+  srsdb     #0x13!                    @ Store return state on SVC stack

+                                      @ We are already in SVC mode

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#2                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(PrefetchAbortEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#3                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(DataAbortEntry):

+  sub       LR,LR,#8

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#4

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(ReservedExceptionEntry):

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#5

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(IrqEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+

+  mov       R0,#6                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+ASM_PFX(FiqEntry):

+  sub       LR,LR,#4

+  srsdb     #0x13!                    @ Store return state on SVC stack

+  cps       #0x13                     @ Switch to SVC for common stack

+  stmfd     SP!,{LR}                  @ Store the link register for the current mode

+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              @ Store the register state

+                                      @ Since we have already switch to SVC R8_fiq - R12_fiq

+                                      @ never get used or saved

+  mov       R0,#7                     @ ExceptionType

+  ldr       R1,ASM_PFX(CommonExceptionEntry)

+  bx        R1

+

+//

+// This gets patched by the C code that patches in the vector table

+//

+ASM_PFX(CommonExceptionEntry):

+  .word       ASM_PFX(AsmCommonExceptionEntry)

+

+ASM_PFX(ExceptionHandlersEnd):

+

+//

+// This code runs from CpuDxe driver loaded address. It is patched into

+// CommonExceptionEntry.

+//

+ASM_PFX(AsmCommonExceptionEntry):

+  mrc       p15, 0, R1, c6, c0, 2   @ Read IFAR

+  str       R1, [SP, #0x50]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR

+

+  mrc       p15, 0, R1, c5, c0, 1   @ Read IFSR

+  str       R1, [SP, #0x4c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR

+

+  mrc       p15, 0, R1, c6, c0, 0   @ Read DFAR

+  str       R1, [SP, #0x48]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR

+

+  mrc       p15, 0, R1, c5, c0, 0   @ Read DFSR

+  str       R1, [SP, #0x44]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

+

+  ldr       R1, [SP, #0x5c]         @ srsdb saved pre-exception CPSR on the stack

+  str       R1, [SP, #0x40]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

+

+  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R3, R1, #0x1f           @ Check CPSR to see if User or System Mode

+  cmp       R3, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1df))

+  cmpne     R3, #0x10               @

+  stmeqed   R2, {lr}^               @   save unbanked lr

+                                    @ else

+  stmneed   R2, {lr}                @   save SVC lr

+

+

+  ldr       R5, [SP, #0x58]         @ PC is the LR pushed by srsfd

+                                    @ Check to see if we have to adjust for Thumb entry

+  sub       r4, r0, #1              @ if (ExceptionType == 1 || ExceptionType ==2)) {

+  cmp       r4, #1                  @   // UND & SVC have differnt LR adjust for Thumb

+  bhi       NoAdjustNeeded

+

+  tst       r1, #0x20               @   if ((CPSR & T)) == T) {  // Thumb Mode on entry

+  addne     R5, R5, #2              @     PC += 2@

+  str       R5,[SP,#0x58]           @ Update LR value pused by srsfd

+

+NoAdjustNeeded:

+

+  str       R5, [SP, #0x3c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC

+

+  sub       R1, SP, #0x60           @ We pused 0x60 bytes on the stack

+  str       R1, [SP, #0x34]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP

+

+                                    @ R0 is ExceptionType

+  mov       R1,SP                   @ R1 is SystemContext

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpush     {d0-d15}                @ save vstm registers in case they are used in optimizations

+#endif

+

+/*

+VOID

+EFIAPI

+DefaultExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1

+  )

+

+*/

+  blx       ASM_PFX(DefaultExceptionHandler)  @ Call exception handler

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpop      {d0-d15}

+#endif

+

+  ldr       R1, [SP, #0x4c]         @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR

+  mcr       p15, 0, R1, c5, c0, 1   @ Write IFSR

+

+  ldr       R1, [SP, #0x44]         @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR

+  mcr       p15, 0, R1, c5, c0, 0   @ Write DFSR

+

+  ldr       R1,[SP,#0x3c]           @ EFI_SYSTEM_CONTEXT_ARM.PC

+  str       R1,[SP,#0x58]           @ Store it back to srsfd stack slot so it can be restored

+

+  ldr       R1,[SP,#0x40]           @ EFI_SYSTEM_CONTEXT_ARM.CPSR

+  str       R1,[SP,#0x5c]           @ Store it back to srsfd stack slot so it can be restored

+

+  add       R3, SP, #0x54           @ Make R3 point to SVC LR saved on entry

+  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R1, R1, #0x1f           @ Check to see if User or System Mode

+  cmp       R1, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1f))

+  cmpne     R1, #0x10               @

+  ldmeqed   R2, {lr}^               @   restore unbanked lr

+                                    @ else

+  ldmneed   R3, {lr}                @   restore SVC lr, via ldmfd SP!, {LR}

+

+  ldmfd     SP!,{R0-R12}            @ Restore general purpose registers

+                                    @ Exception handler can not change SP

+

+  add       SP,SP,#0x20             @ Clear out the remaining stack space

+  ldmfd     SP!,{LR}                @ restore the link register for this context

+  rfefd     SP!                     @ return from exception via srsfd stack slot

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm
new file mode 100644
index 0000000..b879142
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm
@@ -0,0 +1,273 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+// 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/PcdLib.h>

+

+/*

+

+This is the stack constructed by the exception handler (low address to high address)

+                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM

+  Reg   Offset

+  ===   ======

+  R0    0x00    # stmfd     SP!,{R0-R12}

+  R1    0x04

+  R2    0x08

+  R3    0x0c

+  R4    0x10

+  R5    0x14

+  R6    0x18

+  R7    0x1c

+  R8    0x20

+  R9    0x24

+  R10   0x28

+  R11   0x2c

+  R12   0x30

+  SP    0x34    # reserved via adding 0x20 (32) to the SP

+  LR    0x38

+  PC    0x3c

+  CPSR  0x40

+  DFSR  0x44

+  DFAR  0x48

+  IFSR  0x4c

+  IFAR  0x50

+

+  LR    0x54    # SVC Link register (we need to restore it)

+

+  LR    0x58    # pushed by srsfd

+  CPSR  0x5c

+

+ */

+

+  EXPORT  DebugAgentVectorTable

+  IMPORT  DefaultExceptionHandler

+

+  PRESERVE8

+  AREA  DebugAgentException, CODE, READONLY, CODEALIGN, ALIGN=5

+

+//

+// This code gets copied to the ARM vector table

+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied

+//

+DebugAgentVectorTable FUNCTION

+  b   ResetEntry

+  b   UndefinedInstructionEntry

+  b   SoftwareInterruptEntry

+  b   PrefetchAbortEntry

+  b   DataAbortEntry

+  b   ReservedExceptionEntry

+  b   IrqEntry

+  b   FiqEntry

+  ENDFUNC

+

+ResetEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+                                      ; We are already in SVC mode

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#0                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+UndefinedInstructionEntry

+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#1                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry;

+  bx        R1

+

+SoftwareInterruptEntry

+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+                                      ; We are already in SVC mode

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#2                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+PrefetchAbortEntry

+  sub       LR,LR,#4

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#3                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+DataAbortEntry

+  sub       LR,LR,#8

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#4                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+ReservedExceptionEntry

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#5                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+IrqEntry

+  sub       LR,LR,#4

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+

+  mov       R0,#6                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+FiqEntry

+  sub       LR,LR,#4

+  srsfd     #0x13!                    ; Store return state on SVC stack

+  cps       #0x13                     ; Switch to SVC for common stack

+  stmfd     SP!,{LR}                  ; Store the link register for the current mode

+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR

+  stmfd     SP!,{R0-R12}              ; Store the register state

+                                      ; Since we have already switch to SVC R8_fiq - R12_fiq

+                                      ; never get used or saved

+  mov       R0,#7                     ; ExceptionType

+  ldr       R1,CommonExceptionEntry

+  bx        R1

+

+//

+// This gets patched by the C code that patches in the vector table

+//

+CommonExceptionEntry

+  dcd       AsmCommonExceptionEntry

+

+ExceptionHandlersEnd

+

+//

+// This code runs from CpuDxe driver loaded address. It is patched into

+// CommonExceptionEntry.

+//

+AsmCommonExceptionEntry

+  mrc       p15, 0, R1, c6, c0, 2   ; Read IFAR

+  str       R1, [SP, #0x50]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR

+

+  mrc       p15, 0, R1, c5, c0, 1   ; Read IFSR

+  str       R1, [SP, #0x4c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR

+

+  mrc       p15, 0, R1, c6, c0, 0   ; Read DFAR

+  str       R1, [SP, #0x48]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR

+

+  mrc       p15, 0, R1, c5, c0, 0   ; Read DFSR

+  str       R1, [SP, #0x44]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR

+

+  ldr       R1, [SP, #0x5c]         ; srsfd saved pre-exception CPSR on the stack

+  str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR

+

+  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R3, R1, #0x1f           ; Check CPSR to see if User or System Mode

+  cmp       R3, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1df))

+  cmpne     R3, #0x10               ;

+  stmeqed   R2, {lr}^               ;   save unbanked lr

+                                    ; else

+  stmneed   R2, {lr}                ;   save SVC lr

+

+

+  ldr       R5, [SP, #0x58]         ; PC is the LR pushed by srsfd

+                                    ; Check to see if we have to adjust for Thumb entry

+  sub       r4, r0, #1              ; if (ExceptionType == 1 || ExceptionType ==2)) {

+  cmp       r4, #1                  ;   // UND & SVC have differnt LR adjust for Thumb

+  bhi       NoAdjustNeeded

+

+  tst       r1, #0x20               ;   if ((CPSR & T)) == T) {  // Thumb Mode on entry

+  addne     R5, R5, #2              ;     PC += 2;

+  str       R5,[SP,#0x58]           ; Update LR value pused by srsfd

+

+NoAdjustNeeded

+

+  str       R5, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC

+

+  sub       R1, SP, #0x60           ; We pused 0x60 bytes on the stack

+  str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP

+

+                                    ; R0 is ExceptionType

+  mov       R1,SP                   ; R1 is SystemContext

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpush    {d0-d15}                  ; save vstm registers in case they are used in optimizations

+#endif

+

+/*

+VOID

+EFIAPI

+DefaultExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1

+  )

+

+*/

+  blx       DefaultExceptionHandler ; Call exception handler

+

+#if (FixedPcdGet32(PcdVFPEnabled))

+  vpop      {d0-d15}

+#endif

+

+  ldr       R1, [SP, #0x4c]         ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR

+  mcr       p15, 0, R1, c5, c0, 1   ; Write IFSR

+

+  ldr       R1, [SP, #0x44]         ; sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR

+  mcr       p15, 0, R1, c5, c0, 0   ; Write DFSR

+

+  ldr       R1,[SP,#0x3c]           ; EFI_SYSTEM_CONTEXT_ARM.PC

+  str       R1,[SP,#0x58]           ; Store it back to srsfd stack slot so it can be restored

+

+  ldr       R1,[SP,#0x40]           ; EFI_SYSTEM_CONTEXT_ARM.CPSR

+  str       R1,[SP,#0x5c]           ; Store it back to srsfd stack slot so it can be restored

+

+  add       R3, SP, #0x54           ; Make R3 point to SVC LR saved on entry

+  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR

+  and       R1, R1, #0x1f           ; Check to see if User or System Mode

+  cmp       R1, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1f))

+  cmpne     R1, #0x10               ;

+  ldmeqed   R2, {lr}^               ;   restore unbanked lr

+                                    ; else

+  ldmneed   R3, {lr}                ;   restore SVC lr, via ldmfd SP!, {LR}

+

+  ldmfd     SP!,{R0-R12}            ; Restore general purpose registers

+                                    ; Exception handler can not change SP

+

+  add       SP,SP,#0x20             ; Clear out the remaining stack space

+  ldmfd     SP!,{LR}                ; restore the link register for this context

+  rfefd     SP!                     ; return from exception via srsfd stack slot

+

+  END

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c
new file mode 100644
index 0000000..fe5fd55
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c
@@ -0,0 +1,351 @@
+/** @file

+*  Main file supporting the SEC Phase for Versatile Express

+*

+*  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.

+*

+**/

+

+#include <Uefi.h>

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/DebugAgentLib.h>

+#include <Library/PcdLib.h>

+#include <Library/PeCoffExtraActionLib.h>

+#include <Library/PeCoffLib.h>

+

+#include <Pi/PiFirmwareFile.h>

+#include <Pi/PiFirmwareVolume.h>

+

+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \

+  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))

+

+

+// Vector Table for Sec Phase

+VOID

+DebugAgentVectorTable (

+  VOID

+  );

+

+/**

+  Returns the highest bit set of the State field

+

+  @param ErasePolarity   Erase Polarity  as defined by EFI_FVB2_ERASE_POLARITY

+                         in the Attributes field.

+  @param FfsHeader       Pointer to FFS File Header

+

+

+  @retval the highest bit in the State field

+

+**/

+STATIC

+EFI_FFS_FILE_STATE

+GetFileState (

+  IN UINT8                ErasePolarity,

+  IN EFI_FFS_FILE_HEADER  *FfsHeader

+  )

+{

+  EFI_FFS_FILE_STATE  FileState;

+  EFI_FFS_FILE_STATE  HighestBit;

+

+  FileState = FfsHeader->State;

+

+  if (ErasePolarity != 0) {

+    FileState = (EFI_FFS_FILE_STATE)~FileState;

+  }

+

+  HighestBit = 0x80;

+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {

+    HighestBit >>= 1;

+  }

+

+  return HighestBit;

+}

+

+/**

+  Calculates the checksum of the header of a file.

+  The header is a zero byte checksum, so zero means header is good

+

+  @param FfsHeader       Pointer to FFS File Header

+

+  @retval Checksum of the header

+

+**/

+STATIC

+UINT8

+CalculateHeaderChecksum (

+  IN EFI_FFS_FILE_HEADER  *FileHeader

+  )

+{

+  UINT8   Sum;

+

+  // Calculate the sum of the header

+  Sum = CalculateSum8 ((CONST VOID*)FileHeader,sizeof(EFI_FFS_FILE_HEADER));

+

+  // State field (since this indicates the different state of file).

+  Sum = (UINT8)(Sum - FileHeader->State);

+

+  // Checksum field of the file is not part of the header checksum.

+  Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);

+

+  return Sum;

+}

+

+EFI_STATUS

+GetFfsFile (

+  IN  EFI_FIRMWARE_VOLUME_HEADER           *FwVolHeader,

+  IN  EFI_FV_FILETYPE                      FileType,

+  OUT EFI_FFS_FILE_HEADER                  **FileHeader

+  )

+{

+  UINT64                                FvLength;

+  UINTN                                 FileOffset;

+  EFI_FFS_FILE_HEADER                   *FfsFileHeader;

+  UINT8                                 ErasePolarity;

+  UINT8                                 FileState;

+  UINT32                                FileLength;

+  UINT32                                FileOccupiedSize;

+

+  ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);

+

+  FvLength = FwVolHeader->FvLength;

+  FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);

+  FileOffset = FwVolHeader->HeaderLength;

+

+  if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {

+    ErasePolarity = 1;

+  } else {

+    ErasePolarity = 0;

+  }

+

+  while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {

+    // Get FileState which is the highest bit of the State

+    FileState = GetFileState (ErasePolarity, FfsFileHeader);

+

+    switch (FileState) {

+

+    case EFI_FILE_HEADER_INVALID:

+      FileOffset += sizeof(EFI_FFS_FILE_HEADER);

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));

+      break;

+

+    case EFI_FILE_DATA_VALID:

+    case EFI_FILE_MARKED_FOR_UPDATE:

+      if (CalculateHeaderChecksum (FfsFileHeader) != 0) {

+        ASSERT (FALSE);

+        return EFI_NOT_FOUND;

+      }

+

+      if (FfsFileHeader->Type == FileType) {

+        *FileHeader = FfsFileHeader;

+        return EFI_SUCCESS;

+      }

+

+      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;

+      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);

+

+      FileOffset += FileOccupiedSize;

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);

+      break;

+

+    case EFI_FILE_DELETED:

+      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;

+      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);

+      FileOffset += FileOccupiedSize;

+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);

+      break;

+

+    default:

+      return EFI_NOT_FOUND;

+    }

+  }

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+GetImageContext (

+  IN  EFI_FFS_FILE_HEADER           *FfsHeader,

+  OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  EFI_STATUS                              Status;

+  UINTN                                   ParsedLength;

+  UINTN                                   SectionSize;

+  UINTN                                   SectionLength;

+  EFI_COMMON_SECTION_HEADER               *Section;

+  VOID                                    *EfiImage;

+  UINTN                                   ImageAddress;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY         *DebugEntry;

+  VOID                                    *CodeViewEntryPointer;

+

+  Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);

+  SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;

+  SectionSize -= sizeof (EFI_FFS_FILE_HEADER);

+  ParsedLength = 0;

+  EfiImage = NULL;

+

+  while (ParsedLength < SectionSize) {

+    if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {

+      EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(Section + 1);

+      break;

+    }

+

+    //

+    // Size is 24 bits wide so mask upper 8 bits.

+    // SectionLength is adjusted it is 4 byte aligned.

+    // Go to the next section

+    //

+    SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;

+    SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);

+    ASSERT (SectionLength != 0);

+    ParsedLength += SectionLength;

+    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);

+  }

+

+  if (EfiImage == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  // Initialize the Image Context

+  ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));

+  ImageContext->Handle    = EfiImage;

+  ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;

+

+  Status =  PeCoffLoaderGetImageInfo (ImageContext);

+  if (!EFI_ERROR(Status) && ((VOID*)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) {

+    ImageAddress = ImageContext->ImageAddress;

+    if (ImageContext->IsTeImage) {

+      ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER*)EfiImage)->StrippedSize;

+    }

+

+    DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(ImageAddress + ImageContext->DebugDirectoryEntryRva);

+    if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+      CodeViewEntryPointer = (VOID *) (ImageAddress + (UINTN) DebugEntry->RVA);

+      switch (* (UINT32 *) CodeViewEntryPointer) {

+      case CODEVIEW_SIGNATURE_NB10:

+        ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);

+        break;

+      case CODEVIEW_SIGNATURE_RSDS:

+        ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);

+        break;

+      case CODEVIEW_SIGNATURE_MTOC:

+        ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);

+        break;

+      default:

+        break;

+      }

+    }

+  }

+

+  return Status;

+}

+

+/**

+  Initialize debug agent.

+

+  This function is used to set up debug environment to support source level debugging.

+  If certain Debug Agent Library instance has to save some private data in the stack,

+  this function must work on the mode that doesn't return to the caller, then

+  the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one

+  function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is

+  responsible to invoke the passing-in function at the end of InitializeDebugAgent().

+

+  If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by

+  passing in the Context to be its parameter.

+

+  If Function() is NULL, Debug Agent Library instance will return after setup debug

+  environment.

+

+  @param[in] InitFlag     Init flag is used to decide the initialize process.

+  @param[in] Context      Context needed according to InitFlag; it was optional.

+  @param[in] Function     Continue function called by debug agent library; it was

+                          optional.

+

+**/

+VOID

+EFIAPI

+InitializeDebugAgent (

+  IN UINT32                InitFlag,

+  IN VOID                  *Context, OPTIONAL

+  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL

+  )

+{

+  EFI_STATUS            Status;

+  EFI_FFS_FILE_HEADER   *FfsHeader;

+  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;

+

+  // Now we've got UART, check the Debug Agent Vector Table

+  // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure

+  // 'Align=4K' is defined into your FDF for this module.

+  ASSERT (((UINTN)DebugAgentVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);

+  ArmWriteVBar ((UINTN)DebugAgentVectorTable);

+

+  // We use InitFlag to know if DebugAgent has been intialized from

+  // Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC)

+  // modules

+  if (InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) {

+    //

+    // Get the Sec or PrePeiCore module (defined as SEC type module)

+    //

+    Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdSecureFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);

+    if (!EFI_ERROR(Status)) {

+      Status = GetImageContext (FfsHeader,&ImageContext);

+      if (!EFI_ERROR(Status)) {

+        PeCoffLoaderRelocateImageExtraAction (&ImageContext);

+      }

+    }

+  } else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {

+    //

+    // Get the PrePi or PrePeiCore module (defined as SEC type module)

+    //

+    Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);

+    if (!EFI_ERROR(Status)) {

+      Status = GetImageContext (FfsHeader,&ImageContext);

+      if (!EFI_ERROR(Status)) {

+        PeCoffLoaderRelocateImageExtraAction (&ImageContext);

+      }

+    }

+

+    //

+    // Get the PeiCore module (defined as PEI_CORE type module)

+    //

+    Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_PEI_CORE, &FfsHeader);

+    if (!EFI_ERROR(Status)) {

+      Status = GetImageContext (FfsHeader,&ImageContext);

+      if (!EFI_ERROR(Status)) {

+        PeCoffLoaderRelocateImageExtraAction (&ImageContext);

+      }

+    }

+  }

+}

+

+/**

+  Enable/Disable the interrupt of debug timer and return the interrupt state

+  prior to the operation.

+

+  If EnableStatus is TRUE, enable the interrupt of debug timer.

+  If EnableStatus is FALSE, disable the interrupt of debug timer.

+

+  @param[in] EnableStatus    Enable/Disable.

+

+  @return FALSE always.

+

+**/

+BOOLEAN

+EFIAPI

+SaveAndSetDebugTimerInterrupt (

+  IN BOOLEAN                EnableStatus

+  )

+{

+  return FALSE;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
new file mode 100644
index 0000000..6b784f7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
@@ -0,0 +1,47 @@
+#

+#  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                      = DebugAgentSymbolsBaseLib

+  FILE_GUID                      = 9055e2e0-9b33-11e0-a7d7-0002a5d5c51b

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugAgentLib

+

+[Sources.common]

+  DebugAgentSymbolsBaseLib.c

+

+[Sources.ARM]

+  Arm/DebugAgentException.asm        | RVCT

+  Arm/DebugAgentException.S          | GCC

+

+[Sources.AARCH64]

+  AArch64/DebugAgentException.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  DebugLib

+  DefaultExceptionHandlerLib

+  PcdLib

+  PeCoffExtraActionLib

+  PeCoffLib

+

+[Pcd]

+  gArmTokenSpaceGuid.PcdSecureFvBaseAddress

+  gArmTokenSpaceGuid.PcdFvBaseAddress

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
new file mode 100755
index 0000000..41018de
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
@@ -0,0 +1,141 @@
+/**@file

+

+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+Portions 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 <PiDxe.h>

+#include <Library/PeCoffLib.h>

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/PeCoffExtraActionLib.h>

+#include <Library/PrintLib.h>

+

+

+/**

+  If the build is done on cygwin the paths are cygpaths.

+  /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert

+  them to work with RVD commands

+

+  @param  Name  Path to convert if needed

+

+**/

+CHAR8 *

+DeCygwinPathIfNeeded (

+  IN  CHAR8   *Name,

+  IN  CHAR8   *Temp,

+  IN  UINTN   Size

+  )

+{

+  CHAR8   *Ptr;

+  UINTN   Index;

+  UINTN   Index2;

+

+  Ptr = AsciiStrStr (Name, "/cygdrive/");

+  if (Ptr == NULL) {

+    return Name;

+  }

+

+  for (Index = 9, Index2 = 0; (Index < (Size + 9)) && (Ptr[Index] != '\0'); Index++, Index2++) {

+    Temp[Index2] = Ptr[Index];

+    if (Temp[Index2] == '/') {

+      Temp[Index2] = '\\' ;

+  }

+

+    if (Index2 == 1) {

+      Temp[Index2 - 1] = Ptr[Index];

+      Temp[Index2] = ':';

+    }

+  }

+

+  return Temp;

+}

+

+

+/**

+  Performs additional actions after a PE/COFF image has been loaded and relocated.

+

+  If ImageContext is NULL, then ASSERT().

+

+  @param  ImageContext  Pointer to the image context structure that describes the

+                        PE/COFF image that has already been loaded and relocated.

+

+**/

+VOID

+EFIAPI

+PeCoffLoaderRelocateImageExtraAction (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+#if !defined(MDEPKG_NDEBUG)

+  CHAR8 Temp[512];

+#endif

+

+  if (ImageContext->PdbPointer) {

+#ifdef __CC_ARM

+#if (__ARMCC_VERSION < 500000)

+    // Print out the command for the RVD debugger to load symbols for this image

+    DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));

+#else

+    // Print out the command for the DS-5 to load symbols for this image

+    DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));

+#endif

+#elif __GNUC__

+    // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required

+    DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));

+#else

+    DEBUG ((EFI_D_ERROR, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_POINT (ImageContext->EntryPoint)));

+#endif

+  } else {

+    DEBUG ((EFI_D_ERROR, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_POINT (ImageContext->EntryPoint)));

+  }

+}

+

+

+

+/**

+  Performs additional actions just before a PE/COFF image is unloaded.  Any resources

+  that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.

+

+  If ImageContext is NULL, then ASSERT().

+

+  @param  ImageContext  Pointer to the image context structure that describes the

+                        PE/COFF image that is being unloaded.

+

+**/

+VOID

+EFIAPI

+PeCoffLoaderUnloadImageExtraAction (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+#if !defined(MDEPKG_NDEBUG)

+  CHAR8 Temp[512];

+#endif

+

+  if (ImageContext->PdbPointer) {

+#ifdef __CC_ARM

+    // Print out the command for the RVD debugger to load symbols for this image

+    DEBUG ((EFI_D_ERROR, "unload symbols_only %a\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp))));

+#elif __GNUC__

+    // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required

+    DEBUG ((EFI_D_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));

+#else

+    DEBUG ((EFI_D_ERROR, "Unloading %a\n", ImageContext->PdbPointer));

+#endif

+  } else {

+    DEBUG ((EFI_D_ERROR, "Unloading driver at 0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress));

+  }

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
new file mode 100755
index 0000000..c1f717e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
@@ -0,0 +1,39 @@
+#/** @file

+# PeCoff extra action libary for DXE phase that run Unix emulator.

+#

+# Lib to provide memory journal status code reporting Routines

+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DebugUnixPeCoffExtraActionLib

+  FILE_GUID                      = C3E9448E-1726-42fb-9368-41F75B038C0C

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeCoffExtraActionLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = ARM

+#

+

+[Sources.common]

+  DebugPeCoffExtraActionLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c
new file mode 100644
index 0000000..00e01a9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c
@@ -0,0 +1,656 @@
+/** @file

+  Debug version of the UncachedMemoryAllocation lib that uses the VirtualUncachedPages

+  protocol, produced by the DXE CPU driver, to produce debuggable uncached memory buffers.

+

+  The DMA rules for EFI contain the concept of a PCI (DMA master) address for memory and

+  a CPU (C code) address for the memory buffer that don't have to be the same.  There seem to

+  be common errors out there with folks mixing up the two addresses.  This library causes

+  the PCI (DMA master) address to not be mapped into system memory so if the CPU (C code)

+  uses the wrong pointer it will generate a page fault. The CPU (C code) version of the buffer

+  has a virtual address that does not match the physical address. The virtual address has

+  PcdArmUncachedMemoryMask ored into the physical address.

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UncachedMemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Library/ArmLib.h>

+

+#include <Protocol/Cpu.h>

+#include <Protocol/VirtualUncachedPages.h>

+

+VOID *

+UncachedInternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages

+  );

+

+VOID *

+UncachedInternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  );

+

+

+

+EFI_CPU_ARCH_PROTOCOL           *gDebugUncachedCpu;

+VIRTUAL_UNCACHED_PAGES_PROTOCOL *gVirtualUncachedPages;

+

+//

+// Assume all of memory has the same cache attributes, unless we do our magic

+//

+UINT64  gAttributes;

+

+typedef struct {

+  VOID        *Buffer;

+  VOID        *Allocation;

+  UINTN       Pages;

+  LIST_ENTRY  Link;

+} FREE_PAGE_NODE;

+

+LIST_ENTRY  mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);

+

+VOID

+AddPagesToList (

+  IN VOID   *Buffer,

+  IN VOID   *Allocation,

+  UINTN     Pages

+  )

+{

+  FREE_PAGE_NODE  *NewNode;

+

+  NewNode = AllocatePool (sizeof (LIST_ENTRY));

+  if (NewNode == NULL) {

+    ASSERT (FALSE);

+    return;

+  }

+

+  NewNode->Buffer     = Buffer;

+  NewNode->Allocation = Allocation;

+  NewNode->Pages      = Pages;

+

+  InsertTailList (&mPageList, &NewNode->Link);

+}

+

+

+VOID

+RemovePagesFromList (

+  IN VOID   *Buffer,

+  OUT VOID  **Allocation,

+  OUT UINTN *Pages

+  )

+{

+  LIST_ENTRY      *Link;

+  FREE_PAGE_NODE  *OldNode;

+

+  *Allocation = NULL;

+  *Pages = 0;

+

+  for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {

+    OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);

+    if (OldNode->Buffer == Buffer) {

+      *Allocation = OldNode->Allocation;

+      *Pages = OldNode->Pages;

+

+      RemoveEntryList (&OldNode->Link);

+      FreePool (OldNode);

+      return;

+    }

+  }

+

+  return;

+}

+

+

+

+EFI_PHYSICAL_ADDRESS

+ConvertToPhysicalAddress (

+  IN VOID *VirtualAddress

+  )

+{

+  UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);

+  UINTN PhysicalAddress;

+

+  PhysicalAddress = (UINTN)VirtualAddress & ~UncachedMemoryMask;

+

+  return (EFI_PHYSICAL_ADDRESS)PhysicalAddress;

+}

+

+

+VOID *

+ConvertToUncachedAddress (

+  IN VOID *Address

+  )

+{

+  UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);

+  UINTN UncachedAddress;

+

+  UncachedAddress = (UINTN)Address | UncachedMemoryMask;

+

+  return (VOID *)UncachedAddress;

+}

+

+

+

+VOID *

+UncachedInternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages

+  )

+{

+  return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);

+}

+

+

+VOID *

+EFIAPI

+UncachedAllocatePages (

+  IN UINTN  Pages

+  )

+{

+  return UncachedInternalAllocatePages (EfiBootServicesData, Pages);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimePages (

+  IN UINTN  Pages

+  )

+{

+  return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedPages (

+  IN UINTN  Pages

+  )

+{

+  return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);

+}

+

+

+

+VOID

+EFIAPI

+UncachedFreePages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  UncachedFreeAlignedPages (Buffer, Pages);

+  return;

+}

+

+

+VOID *

+UncachedInternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory;

+  EFI_PHYSICAL_ADDRESS  AlignedMemory;

+  UINTN                 AlignmentMask;

+  UINTN                 UnalignedPages;

+  UINTN                 RealPages;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  if (Pages == 0) {

+    return NULL;

+  }

+  if (Alignment > EFI_PAGE_SIZE) {

+    //

+    // Caculate the total number of pages since alignment is larger than page size.

+    //

+    AlignmentMask  = Alignment - 1;

+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);

+    //

+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.

+    //

+    ASSERT (RealPages > Pages);

+

+    Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;

+    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);

+    if (UnalignedPages > 0) {

+      //

+      // Free first unaligned page(s).

+      //

+      Status = gBS->FreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));

+    UnalignedPages = RealPages - Pages - UnalignedPages;

+    if (UnalignedPages > 0) {

+      //

+      // Free last unaligned page(s).

+      //

+      Status = gBS->FreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+  } else {

+    //

+    // Do not over-allocate pages in this case.

+    //

+    Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = (UINTN) Memory;

+  }

+

+  Status = gVirtualUncachedPages->ConvertPages (gVirtualUncachedPages, AlignedMemory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), &gAttributes);

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+

+  AlignedMemory = (EFI_PHYSICAL_ADDRESS)(UINTN)ConvertToUncachedAddress ((VOID *)(UINTN)AlignedMemory);

+

+  return (VOID *)(UINTN)AlignedMemory;

+}

+

+

+VOID

+EFIAPI

+UncachedFreeAlignedPages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory;

+

+  ASSERT (Pages != 0);

+

+  Memory = ConvertToPhysicalAddress (Buffer);

+

+  Status = gVirtualUncachedPages->RevertPages (gVirtualUncachedPages, Memory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), gAttributes);

+

+

+  Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Memory, Pages);

+  ASSERT_EFI_ERROR (Status);

+}

+

+

+

+

+VOID *

+UncachedInternalAllocateAlignedPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID      *AlignedAddress;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  if (Alignment < EFI_PAGE_SIZE) {

+    Alignment = EFI_PAGE_SIZE;

+  }

+

+  AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);

+  if (AlignedAddress == NULL) {

+    return NULL;

+  }

+

+  AddPagesToList ((VOID *)(UINTN)ConvertToPhysicalAddress (AlignedAddress), (VOID *)(UINTN)AlignedAddress, EFI_SIZE_TO_PAGES (AllocationSize));

+

+  return (VOID *) AlignedAddress;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimePool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+VOID *

+UncachedInternalAllocateAlignedZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID    *Memory;

+  Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimeZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+VOID *

+UncachedInternalAllocateAlignedCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer,

+  IN UINTN            Alignment

+  )

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);

+}

+

+VOID

+EFIAPI

+UncachedFreeAlignedPool (

+  IN VOID   *Buffer

+  )

+{

+  VOID    *Allocation;

+  UINTN   Pages;

+

+  RemovePagesFromList (Buffer, &Allocation, &Pages);

+

+  UncachedFreePages (Allocation, Pages);

+}

+

+VOID *

+UncachedInternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            AllocationSize

+  )

+{

+  UINTN CacheLineLength = ArmDataCacheLineLength ();

+  return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);

+}

+

+VOID *

+EFIAPI

+UncachedAllocatePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);

+}

+

+VOID *

+UncachedInternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize

+  )

+{

+  VOID  *Memory;

+

+  Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimeZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);

+}

+

+VOID *

+UncachedInternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  )

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);

+}

+

+VOID

+EFIAPI

+UncachedFreePool (

+  IN VOID   *Buffer

+  )

+{

+  UncachedFreeAlignedPool (Buffer);

+}

+

+VOID

+EFIAPI

+UncachedSafeFreePool (

+  IN VOID   *Buffer

+  )

+{

+  if (Buffer != NULL) {

+    UncachedFreePool (Buffer);

+    Buffer = NULL;

+  }

+}

+

+/**

+  The constructor function caches the pointer of DXE Services Table.

+

+  The constructor function caches the pointer of DXE Services Table.

+  It will ASSERT() if that operation fails.

+  It will ASSERT() if the pointer of DXE Services Table is NULL.

+  It will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+DebugUncachedMemoryAllocationLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS    Status;

+

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gDebugUncachedCpu);

+  ASSERT_EFI_ERROR(Status);

+

+  Status = gBS->LocateProtocol (&gVirtualUncachedPagesProtocolGuid, NULL, (VOID **)&gVirtualUncachedPages);

+  ASSERT_EFI_ERROR(Status);

+

+  return Status;

+}

+

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
new file mode 100644
index 0000000..213188a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
@@ -0,0 +1,47 @@
+#/** @file

+#

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UncachedMemoryAllocationLib

+  FILE_GUID                      = 3C1EA826-696A-4E8A-B89D-3C5369B84F2A

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UncachedMemoryAllocationLib

+  CONSTRUCTOR                    = DebugUncachedMemoryAllocationLibConstructor

+

+[Sources.common]

+  DebugUncachedMemoryAllocationLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  MemoryAllocationLib

+  ArmLib

+

+[Protocols]

+  gEfiCpuArchProtocolGuid

+  gVirtualUncachedPagesProtocolGuid

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask

+

+

+[Depex]

+  gEfiCpuArchProtocolGuid AND gVirtualUncachedPagesProtocolGuid

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
new file mode 100644
index 0000000..49d36ed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
@@ -0,0 +1,187 @@
+/** @file

+  Default exception handler

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+  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 <Uefi.h>

+#include <Library/UefiLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeCoffGetEntryPointLib.h>

+#include <Library/PrintLib.h>

+#include <Library/ArmDisassemblerLib.h>

+#include <Library/SerialPortLib.h>

+

+#include <Guid/DebugImageInfoTable.h>

+#include <Protocol/DebugSupport.h>

+#include <Protocol/LoadedImage.h>

+

+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;

+

+STATIC CHAR8 *gExceptionTypeString[] = {

+  "Synchronous",

+  "IRQ",

+  "FIQ",

+  "SError"

+};

+

+CHAR8 *

+GetImageName (

+  IN  UINTN  FaultAddress,

+  OUT UINTN  *ImageBase,

+  OUT UINTN  *PeCoffSizeOfHeaders

+  );

+

+STATIC

+VOID

+DescribeInstructionOrDataAbort (

+  IN CHAR8 *AbortType,

+  IN UINTN Iss

+  )

+{

+  CHAR8 *AbortCause;

+

+  switch (Iss & 0x3f) {

+    case 0x0: AbortCause = "Address size fault, zeroth level of translation or translation table base register";  break;

+    case 0x1: AbortCause = "Address size fault, first level";  break;

+    case 0x2: AbortCause = "Address size fault, second level";  break;

+    case 0x3: AbortCause = "Address size fault, third level";  break;

+    case 0x4: AbortCause = "Translation fault, zeroth level";  break;

+    case 0x5: AbortCause = "Translation fault, first level";  break;

+    case 0x6: AbortCause = "Translation fault, second level";  break;

+    case 0x7: AbortCause = "Translation fault, third level";  break;

+    case 0x9: AbortCause = "Access flag fault, first level";  break;

+    case 0xa: AbortCause = "Access flag fault, second level";  break;

+    case 0xb: AbortCause = "Access flag fault, third level";  break;

+    case 0xd: AbortCause = "Permission fault, first level";  break;

+    case 0xe: AbortCause = "Permission fault, second level";  break;

+    case 0xf: AbortCause = "Permission fault, third level";  break;

+    case 0x10: AbortCause = "Synchronous external abort";  break;

+    case 0x18: AbortCause = "Synchronous parity error on memory access";  break;

+    case 0x11: AbortCause = "Asynchronous external abort";  break;

+    case 0x19: AbortCause = "Asynchronous parity error on memory access";  break;

+    case 0x14: AbortCause = "Synchronous external abort on translation table walk, zeroth level";  break;

+    case 0x15: AbortCause = "Synchronous external abort on translation table walk, first level";  break;

+    case 0x16: AbortCause = "Synchronous external abort on translation table walk, second level";  break;

+    case 0x17: AbortCause = "Synchronous external abort on translation table walk, third level";  break;

+    case 0x1c: AbortCause = "Synchronous parity error on memory access on translation table walk, zeroth level";  break;

+    case 0x1d: AbortCause = "Synchronous parity error on memory access on translation table walk, first level";  break;

+    case 0x1e: AbortCause = "Synchronous parity error on memory access on translation table walk, second level";  break;

+    case 0x1f: AbortCause = "Synchronous parity error on memory access on translation table walk, third level";  break;

+    case 0x21: AbortCause = "Alignment fault";  break;

+    case 0x22: AbortCause = "Debug event";  break;

+    case 0x30: AbortCause = "TLB conflict abort";  break;

+    case 0x33:

+    case 0x34: AbortCause = "IMPLEMENTATION DEFINED";  break;

+    case 0x35:

+    case 0x36: AbortCause = "Domain fault"; break;

+    default: AbortCause = ""; break;

+  }

+

+  DEBUG ((EFI_D_ERROR, "\n%a: %a\n", AbortType, AbortCause));

+}

+

+STATIC

+VOID

+DescribeExceptionSyndrome (

+  IN UINT32 Esr

+  )

+{

+  CHAR8 *Message;

+  UINTN Ec;

+  UINTN Iss;

+

+  Ec = Esr >> 26;

+  Iss = Esr & 0x00ffffff;

+

+  switch (Ec) {

+    case 0x15: Message = "SVC executed in AArch64"; break;

+    case 0x20:

+    case 0x21: DescribeInstructionOrDataAbort ("Instruction abort", Iss); return;

+    case 0x22: Message = "PC alignment fault"; break;

+    case 0x23: Message = "SP alignment fault"; break;

+    case 0x24:

+    case 0x25: DescribeInstructionOrDataAbort ("Data abort", Iss); return;

+    default: return;

+  }

+

+  DEBUG ((EFI_D_ERROR, "\n %a \n", Message));

+}

+

+/**

+  This is the default action to take on an unexpected exception

+

+  Since this is exception context don't do anything crazy like try to allcoate memory.

+

+  @param  ExceptionType    Type of the exception

+  @param  SystemContext    Register state at the time of the Exception

+

+**/

+VOID

+DefaultExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  CHAR8  Buffer[100];

+  UINTN  CharCount;

+

+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n\n%a Exception at 0x%016lx\n", gExceptionTypeString[ExceptionType], SystemContext.SystemContextAArch64->ELR);

+  SerialPortWrite ((UINT8 *) Buffer, CharCount);

+

+  DEBUG_CODE_BEGIN ();

+    CHAR8  *Pdb;

+    UINTN  ImageBase;

+    UINTN  PeCoffSizeOfHeader;

+    Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader);

+    if (Pdb != NULL) {

+      DEBUG ((EFI_D_ERROR, "%a loaded at 0x%016lx \n", Pdb, ImageBase));

+    }

+  DEBUG_CODE_END ();

+

+  DEBUG ((EFI_D_ERROR, "\n  X0 0x%016lx   X1 0x%016lx   X2 0x%016lx   X3 0x%016lx\n", SystemContext.SystemContextAArch64->X0, SystemContext.SystemContextAArch64->X1, SystemContext.SystemContextAArch64->X2, SystemContext.SystemContextAArch64->X3));

+  DEBUG ((EFI_D_ERROR, "  X4 0x%016lx   X5 0x%016lx   X6 0x%016lx   X7 0x%016lx\n", SystemContext.SystemContextAArch64->X4, SystemContext.SystemContextAArch64->X5, SystemContext.SystemContextAArch64->X6, SystemContext.SystemContextAArch64->X7));

+  DEBUG ((EFI_D_ERROR, "  X8 0x%016lx   X9 0x%016lx  X10 0x%016lx  X11 0x%016lx\n", SystemContext.SystemContextAArch64->X8, SystemContext.SystemContextAArch64->X9, SystemContext.SystemContextAArch64->X10, SystemContext.SystemContextAArch64->X11));

+  DEBUG ((EFI_D_ERROR, " X12 0x%016lx  X13 0x%016lx  X14 0x%016lx  X15 0x%016lx\n", SystemContext.SystemContextAArch64->X12, SystemContext.SystemContextAArch64->X13, SystemContext.SystemContextAArch64->X14, SystemContext.SystemContextAArch64->X15));

+  DEBUG ((EFI_D_ERROR, " X16 0x%016lx  X17 0x%016lx  X18 0x%016lx  X19 0x%016lx\n", SystemContext.SystemContextAArch64->X16, SystemContext.SystemContextAArch64->X17, SystemContext.SystemContextAArch64->X18, SystemContext.SystemContextAArch64->X19));

+  DEBUG ((EFI_D_ERROR, " X20 0x%016lx  X21 0x%016lx  X22 0x%016lx  X23 0x%016lx\n", SystemContext.SystemContextAArch64->X20, SystemContext.SystemContextAArch64->X21, SystemContext.SystemContextAArch64->X22, SystemContext.SystemContextAArch64->X23));

+  DEBUG ((EFI_D_ERROR, " X24 0x%016lx  X25 0x%016lx  X26 0x%016lx  X27 0x%016lx\n", SystemContext.SystemContextAArch64->X24, SystemContext.SystemContextAArch64->X25, SystemContext.SystemContextAArch64->X26, SystemContext.SystemContextAArch64->X27));

+  DEBUG ((EFI_D_ERROR, " X28 0x%016lx   FP 0x%016lx   LR 0x%016lx  \n", SystemContext.SystemContextAArch64->X28, SystemContext.SystemContextAArch64->FP, SystemContext.SystemContextAArch64->LR));

+

+  /* We save these as 128bit numbers, but have to print them as two 64bit numbers,

+     so swap the 64bit words to correctly represent a 128bit number.  */

+  DEBUG ((EFI_D_ERROR, "\n  V0 0x%016lx %016lx   V1 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V0[1], SystemContext.SystemContextAArch64->V0[0], SystemContext.SystemContextAArch64->V1[1], SystemContext.SystemContextAArch64->V1[0]));

+  DEBUG ((EFI_D_ERROR, "  V2 0x%016lx %016lx   V3 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V2[1], SystemContext.SystemContextAArch64->V2[0], SystemContext.SystemContextAArch64->V3[1], SystemContext.SystemContextAArch64->V3[0]));

+  DEBUG ((EFI_D_ERROR, "  V4 0x%016lx %016lx   V5 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V4[1], SystemContext.SystemContextAArch64->V4[0], SystemContext.SystemContextAArch64->V5[1], SystemContext.SystemContextAArch64->V5[0]));

+  DEBUG ((EFI_D_ERROR, "  V6 0x%016lx %016lx   V7 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V6[1], SystemContext.SystemContextAArch64->V6[0], SystemContext.SystemContextAArch64->V7[1], SystemContext.SystemContextAArch64->V7[0]));

+  DEBUG ((EFI_D_ERROR, "  V8 0x%016lx %016lx   V9 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V8[1], SystemContext.SystemContextAArch64->V8[0], SystemContext.SystemContextAArch64->V9[1], SystemContext.SystemContextAArch64->V9[0]));

+  DEBUG ((EFI_D_ERROR, " V10 0x%016lx %016lx  V11 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V10[1], SystemContext.SystemContextAArch64->V10[0], SystemContext.SystemContextAArch64->V11[1], SystemContext.SystemContextAArch64->V11[0]));

+  DEBUG ((EFI_D_ERROR, " V12 0x%016lx %016lx  V13 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V12[1], SystemContext.SystemContextAArch64->V12[0], SystemContext.SystemContextAArch64->V13[1], SystemContext.SystemContextAArch64->V13[0]));

+  DEBUG ((EFI_D_ERROR, " V14 0x%016lx %016lx  V15 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V14[1], SystemContext.SystemContextAArch64->V14[0], SystemContext.SystemContextAArch64->V15[1], SystemContext.SystemContextAArch64->V15[0]));

+  DEBUG ((EFI_D_ERROR, " V16 0x%016lx %016lx  V17 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V16[1], SystemContext.SystemContextAArch64->V16[0], SystemContext.SystemContextAArch64->V17[1], SystemContext.SystemContextAArch64->V17[0]));

+  DEBUG ((EFI_D_ERROR, " V18 0x%016lx %016lx  V19 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V18[1], SystemContext.SystemContextAArch64->V18[0], SystemContext.SystemContextAArch64->V19[1], SystemContext.SystemContextAArch64->V19[0]));

+  DEBUG ((EFI_D_ERROR, " V20 0x%016lx %016lx  V21 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V20[1], SystemContext.SystemContextAArch64->V20[0], SystemContext.SystemContextAArch64->V21[1], SystemContext.SystemContextAArch64->V21[0]));

+  DEBUG ((EFI_D_ERROR, " V22 0x%016lx %016lx  V23 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V22[1], SystemContext.SystemContextAArch64->V22[0], SystemContext.SystemContextAArch64->V23[1], SystemContext.SystemContextAArch64->V23[0]));

+  DEBUG ((EFI_D_ERROR, " V24 0x%016lx %016lx  V25 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V24[1], SystemContext.SystemContextAArch64->V24[0], SystemContext.SystemContextAArch64->V25[1], SystemContext.SystemContextAArch64->V25[0]));

+  DEBUG ((EFI_D_ERROR, " V26 0x%016lx %016lx  V27 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V26[1], SystemContext.SystemContextAArch64->V26[0], SystemContext.SystemContextAArch64->V27[1], SystemContext.SystemContextAArch64->V27[0]));

+  DEBUG ((EFI_D_ERROR, " V28 0x%016lx %016lx  V29 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V28[1], SystemContext.SystemContextAArch64->V28[0], SystemContext.SystemContextAArch64->V29[1], SystemContext.SystemContextAArch64->V29[0]));

+  DEBUG ((EFI_D_ERROR, " V30 0x%016lx %016lx  V31 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V30[1], SystemContext.SystemContextAArch64->V30[0], SystemContext.SystemContextAArch64->V31[1], SystemContext.SystemContextAArch64->V31[0]));

+

+  DEBUG ((EFI_D_ERROR, "\n  SP 0x%016lx  ELR 0x%016lx  SPSR 0x%08lx  FPSR 0x%08lx\n ESR 0x%08lx          FAR 0x%016lx\n", SystemContext.SystemContextAArch64->SP, SystemContext.SystemContextAArch64->ELR, SystemContext.SystemContextAArch64->SPSR, SystemContext.SystemContextAArch64->FPSR, SystemContext.SystemContextAArch64->ESR, SystemContext.SystemContextAArch64->FAR));

+

+  DEBUG ((EFI_D_ERROR, "\n ESR : EC 0x%02x  IL 0x%x  ISS 0x%08x\n", (SystemContext.SystemContextAArch64->ESR & 0xFC000000) >> 26, (SystemContext.SystemContextAArch64->ESR >> 25) & 0x1, SystemContext.SystemContextAArch64->ESR & 0x1FFFFFF ));

+

+  DescribeExceptionSyndrome (SystemContext.SystemContextAArch64->ESR);

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c
new file mode 100644
index 0000000..179fc22
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c
@@ -0,0 +1,268 @@
+/** @file

+  Default exception handler

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 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 <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeCoffGetEntryPointLib.h>

+#include <Library/PrintLib.h>

+#include <Library/ArmDisassemblerLib.h>

+#include <Library/SerialPortLib.h>

+

+#include <Guid/DebugImageInfoTable.h>

+

+#include <Protocol/DebugSupport.h>

+#include <Library/DefaultExceptionHandlerLib.h>

+

+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;

+

+typedef struct {

+  UINT32  BIT;

+  CHAR8   Char;

+} CPSR_CHAR;

+

+CHAR8 *

+GetImageName (

+  IN  UINTN  FaultAddress,

+  OUT UINTN  *ImageBase,

+  OUT UINTN  *PeCoffSizeOfHeaders

+  );

+

+/**

+  Convert the Current Program Status Register (CPSR) to a string. The string is

+  a defacto standard in the ARM world.

+

+  It is possible to add extra bits by adding them to CpsrChar array.

+

+  @param  Cpsr         ARM CPSR register value

+  @param  ReturnStr    32 byte string that contains string version of CPSR

+

+**/

+VOID

+CpsrString (

+  IN  UINT32  Cpsr,

+  OUT CHAR8   *ReturnStr

+  )

+{

+  UINTN     Index;

+  CHAR8*    Str;

+  CHAR8*    ModeStr;

+  CPSR_CHAR CpsrChar[] = {

+    { 31, 'n' },

+    { 30, 'z' },

+    { 29, 'c' },

+    { 28, 'v' },

+

+    { 9,  'e' },

+    { 8,  'a' },

+    { 7,  'i' },

+    { 6,  'f' },

+    { 5,  't' },

+    { 0,  '?' }

+  };

+

+  Str = ReturnStr;

+

+  for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {

+    *Str = CpsrChar[Index].Char;

+    if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {

+      // Concert to upper case if bit is set

+      *Str &= ~0x20;

+    }

+  }

+

+  *Str++ = '_';

+  *Str = '\0';

+

+  switch (Cpsr & 0x1f) {

+  case 0x10:

+    ModeStr = "usr";

+    break;

+  case 0x011:

+    ModeStr = "fiq";

+    break;

+  case 0x12:

+    ModeStr = "irq";

+    break;

+  case 0x13:

+    ModeStr = "svc";

+    break;

+  case 0x16:

+    ModeStr = "mon";

+    break;

+  case 0x17:

+    ModeStr = "abt";

+    break;

+  case 0x1b:

+    ModeStr = "und";

+    break;

+  case 0x1f:

+    ModeStr = "sys";

+    break;

+

+  default:

+    ModeStr = "???";

+    break;

+  }

+

+  AsciiStrCat (Str, ModeStr);

+  return;

+}

+

+CHAR8 *

+FaultStatusToString (

+  IN  UINT32  Status

+  )

+{

+  CHAR8 *FaultSource;

+

+  switch (Status) {

+    case 0x01: FaultSource = "Alignment fault"; break;

+    case 0x02: FaultSource = "Debug event fault"; break;

+    case 0x03: FaultSource = "Access Flag fault on Section"; break;

+    case 0x04: FaultSource = "Cache maintenance operation fault[2]"; break;

+    case 0x05: FaultSource = "Translation fault on Section"; break;

+    case 0x06: FaultSource = "Access Flag fault on Page"; break;

+    case 0x07: FaultSource = "Translation fault on Page"; break;

+    case 0x08: FaultSource = "Precise External Abort"; break;

+    case 0x09: FaultSource = "Domain fault on Section"; break;

+    case 0x0b: FaultSource = "Domain fault on Page"; break;

+    case 0x0c: FaultSource = "External abort on translation, first level"; break;

+    case 0x0d: FaultSource = "Permission fault on Section"; break;

+    case 0x0e: FaultSource = "External abort on translation, second level"; break;

+    case 0x0f: FaultSource = "Permission fault on Page"; break;

+    case 0x16: FaultSource = "Imprecise External Abort"; break;

+    default:   FaultSource = "No function"; break;

+    }

+

+  return FaultSource;

+}

+

+STATIC CHAR8 *gExceptionTypeString[] = {

+  "Reset",

+  "Undefined OpCode",

+  "SVC",

+  "Prefetch Abort",

+  "Data Abort",

+  "Undefined",

+  "IRQ",

+  "FIQ"

+};

+

+/**

+  This is the default action to take on an unexpected exception

+

+  Since this is exception context don't do anything crazy like try to allcoate memory.

+

+  @param  ExceptionType    Type of the exception

+  @param  SystemContext    Register state at the time of the Exception

+

+

+**/

+VOID

+DefaultExceptionHandler (

+  IN     EFI_EXCEPTION_TYPE           ExceptionType,

+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  CHAR8     Buffer[100];

+  UINTN     CharCount;

+  UINT32    DfsrStatus;

+  UINT32    IfsrStatus;

+  BOOLEAN   DfsrWrite;

+  UINT32    PcAdjust = 0;

+

+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x  CPSR 0x%08x ",

+         gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);

+  SerialPortWrite ((UINT8 *) Buffer, CharCount);

+

+  DEBUG_CODE_BEGIN ();

+    CHAR8   *Pdb;

+    UINT32  ImageBase;

+    UINT32  PeCoffSizeOfHeader;

+    UINT32  Offset;

+    CHAR8   CpsrStr[32];  // char per bit. Lower 5-bits are mode that is a 3 char string

+    CHAR8   Buffer[80];

+    UINT8   *DisAsm;

+    UINT32  ItBlock;

+

+    CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);

+    DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));

+

+    Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);

+    Offset = SystemContext.SystemContextArm->PC - ImageBase;

+    if (Pdb != NULL) {

+      DEBUG ((EFI_D_ERROR, "%a\n", Pdb));

+

+      //

+      // A PE/COFF image loads its headers into memory so the headers are

+      // included in the linked addresses. ELF and Mach-O images do not

+      // include the headers so the first byte of the image is usually

+      // text (code). If you look at link maps from ELF or Mach-O images

+      // you need to subtract out the size of the PE/COFF header to get

+      // get the offset that matches the link map.

+      //

+      DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));

+

+      // If we come from an image it is safe to show the instruction. We know it should not fault

+      DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;

+      ItBlock = 0;

+      DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, TRUE, &ItBlock, Buffer, sizeof (Buffer));

+      DEBUG ((EFI_D_ERROR, "\n%a", Buffer));

+

+      switch (ExceptionType) {

+      case EXCEPT_ARM_UNDEFINED_INSTRUCTION:

+      case EXCEPT_ARM_SOFTWARE_INTERRUPT:

+      case EXCEPT_ARM_PREFETCH_ABORT:

+      case EXCEPT_ARM_DATA_ABORT:

+        // advance PC past the faulting instruction

+        PcAdjust = (UINTN)DisAsm - SystemContext.SystemContextArm->PC;

+        break;

+

+      default:

+        break;

+      }

+

+    }

+  DEBUG_CODE_END ();

+  DEBUG ((EFI_D_ERROR, "\n  R0 0x%08x   R1 0x%08x   R2 0x%08x   R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));

+  DEBUG ((EFI_D_ERROR, "  R4 0x%08x   R5 0x%08x   R6 0x%08x   R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));

+  DEBUG ((EFI_D_ERROR, "  R8 0x%08x   R9 0x%08x  R10 0x%08x  R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));

+  DEBUG ((EFI_D_ERROR, " R12 0x%08x   SP 0x%08x   LR 0x%08x   PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));

+  DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));

+

+  // Bit10 is Status[4] Bit3:0 is Status[3:0]

+  DfsrStatus = (SystemContext.SystemContextArm->DFSR & 0xf) | ((SystemContext.SystemContextArm->DFSR >> 6) & 0x10);

+  DfsrWrite = (SystemContext.SystemContextArm->DFSR & BIT11) != 0;

+  if (DfsrStatus != 0x00) {

+    DEBUG ((EFI_D_ERROR, " %a: %a 0x%08x\n", FaultStatusToString (DfsrStatus), DfsrWrite ? "write to" : "read from", SystemContext.SystemContextArm->DFAR));

+  }

+

+  IfsrStatus = (SystemContext.SystemContextArm->IFSR & 0xf) | ((SystemContext.SystemContextArm->IFSR >> 6) & 0x10);

+  if (IfsrStatus != 0) {

+    DEBUG ((EFI_D_ERROR, " Instruction %a at 0x%08x\n", FaultStatusToString (SystemContext.SystemContextArm->IFSR & 0xf), SystemContext.SystemContextArm->IFAR));

+  }

+

+  DEBUG ((EFI_D_ERROR, "\n"));

+  ASSERT (FALSE);

+

+  // Clear the error registers that we have already displayed incase some one wants to keep going

+  SystemContext.SystemContextArm->DFSR = 0;

+  SystemContext.SystemContextArm->IFSR = 0;

+

+  // If some one is stepping past the exception handler adjust the PC to point to the next instruction

+  SystemContext.SystemContextArm->PC += PcAdjust;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerBase.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerBase.c
new file mode 100644
index 0000000..4a54298
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerBase.c
@@ -0,0 +1,35 @@
+/** @file

+

+  Copyright (c) 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>

+

+/**

+

+  @param  FaultAddress         Address to find PE/COFF image for.

+  @param  ImageBase            Return load address of found image

+  @param  PeCoffSizeOfHeaders  Return the size of the PE/COFF header for the image that was found

+

+  @retval NULL                 FaultAddress not in a loaded PE/COFF image.

+  @retval                      Path and file name of PE/COFF image.

+

+**/

+CHAR8 *

+GetImageName (

+  IN  UINTN  FaultAddress,

+  OUT UINTN  *ImageBase,

+  OUT UINTN  *PeCoffSizeOfHeaders

+  )

+{

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
new file mode 100644
index 0000000..da8190b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
@@ -0,0 +1,45 @@
+#/** @file

+#

+#  Copyright (c) 2008, Apple Inc. All rights reserved.<BR>

+#  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.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DefaultExceptionHandlerLib

+  FILE_GUID                      = EACDB354-DF1A-4AF9-A171-499737ED818F

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DefaultExceptionHandlerLib

+  CONSTRUCTOR                    = DefaultExceptionHandlerConstructor

+

+[Sources.common]

+  DefaultExceptionHandlerUefi.c

+

+[Sources.ARM]

+  Arm/DefaultExceptionHandler.c

+

+[Sources.AARCH64]

+  AArch64/DefaultExceptionHandler.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  UefiLib

+  BaseLib

+  PrintLib

+  DebugLib

+  PeCoffGetEntryPointLib

+  ArmDisassemblerLib

+  SerialPortLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
new file mode 100644
index 0000000..8f5b3e1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
@@ -0,0 +1,42 @@
+#/** @file

+#

+# Copyright (c) 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                      = DefaultExceptionHandlerBaseLib

+  FILE_GUID                      = 3d5261d5-5eb7-4559-98e7-475aa9d0dc42

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DefaultExceptionHandlerLib

+

+[Sources.common]

+  DefaultExceptionHandlerBase.c

+

+[Sources.ARM]

+  Arm/DefaultExceptionHandler.c

+

+[Sources.AARCH64]

+  AArch64/DefaultExceptionHandler.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  PrintLib

+  DebugLib

+  PeCoffGetEntryPointLib

+  ArmDisassemblerLib

+  SerialPortLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c
new file mode 100644
index 0000000..b2d630c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c
@@ -0,0 +1,96 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Uefi.h>

+#include <Library/PeCoffGetEntryPointLib.h>

+#include <Library/UefiLib.h>

+

+#include <Guid/DebugImageInfoTable.h>

+

+extern EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader;

+

+/**

+  The constructor function caches EFI Debug table information for use in the exception handler.

+

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+DefaultExceptionHandlerConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);

+  if (EFI_ERROR (Status)) {

+    gDebugImageTableHeader = NULL;

+  }

+  return Status;

+}

+

+/**

+  Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image

+  it came from. As long as the PE/COFF image contains a debug directory entry a

+  string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF

+  image. Microsoft tools contain a pointer to the PDB file that contains the debug information.

+

+  @param  FaultAddress         Address to find PE/COFF image for.

+  @param  ImageBase            Return load address of found image

+  @param  PeCoffSizeOfHeaders  Return the size of the PE/COFF header for the image that was found

+

+  @retval NULL                 FaultAddress not in a loaded PE/COFF image.

+  @retval                      Path and file name of PE/COFF image.

+

+**/

+CHAR8 *

+GetImageName (

+  IN  UINTN  FaultAddress,

+  OUT UINTN  *ImageBase,

+  OUT UINTN  *PeCoffSizeOfHeaders

+  )

+{

+  EFI_DEBUG_IMAGE_INFO  *DebugTable;

+  UINTN                 Entry;

+  CHAR8                 *Address;

+

+  DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;

+  if (DebugTable == NULL) {

+    return NULL;

+  }

+

+  Address = (CHAR8 *)(UINTN)FaultAddress;

+  for (Entry = 0; Entry < gDebugImageTableHeader->TableSize; Entry++, DebugTable++) {

+    if (DebugTable->NormalImage != NULL) {

+      if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&

+          (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {

+        if ((Address >= (CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) &&

+            (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) {

+          *ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;

+          *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);

+          return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);

+        }

+      }

+    }

+  }

+

+  return NULL;

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
new file mode 100644
index 0000000..c2a4a35
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
@@ -0,0 +1,62 @@
+/** @file

+  PEI Services Table Pointer Library.

+

+  This library is used for PEIM which does executed from flash device directly but

+  executed in memory.

+

+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>

+  Copyright (c) 2011 Hewlett-Packard Corporation. 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 <PiPei.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Caches a pointer PEI Services Table.

+

+  Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer

+  in a platform specific manner.

+

+  If PeiServicesTablePointer is NULL, then ASSERT().

+

+  @param    PeiServicesTablePointer   The address of PeiServices pointer.

+**/

+VOID

+EFIAPI

+SetPeiServicesTablePointer (

+  IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer

+  )

+{

+  ArmWriteTpidrurw((UINTN)PeiServicesTablePointer);

+}

+

+/**

+  Retrieves the cached value of the PEI Services Table pointer.

+

+  Returns the cached value of the PEI Services Table pointer in a CPU specific manner

+  as specified in the CPU binding section of the Platform Initialization Pre-EFI

+  Initialization Core Interface Specification.

+

+  If the cached PEI Services Table pointer is NULL, then ASSERT().

+

+  @return  The pointer to PeiServices.

+

+**/

+CONST EFI_PEI_SERVICES **

+EFIAPI

+GetPeiServicesTablePointer (

+  VOID

+  )

+{

+  return (CONST EFI_PEI_SERVICES **)ArmReadTpidrurw();

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
new file mode 100644
index 0000000..fd75977
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
@@ -0,0 +1,45 @@
+## @file

+# Instance of PEI Services Table Pointer Library using global variable for the table pointer.

+#

+# PEI Services Table Pointer Library implementation that retrieves a pointer to the

+#  PEI Services Table from a global variable. Not available to modules that execute from

+#  read-only memory.

+#

+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>

+# Copyright (c) 2011 Hewlett-Packard Corporation. 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                      = PeiServicesTablePointerLib

+  FILE_GUID                      = C3C9C4ED-EB8A-4548-BE1B-ABB0B6F35B1E

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeiServicesTablePointerLib|PEIM PEI_CORE SEC

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiServicesTablePointer.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  DebugLib

+

+[Pcd]

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c
new file mode 100644
index 0000000..abe3c37
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c
@@ -0,0 +1,156 @@
+/**@file

+

+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+Portions 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 <PiDxe.h>

+#include <Library/PeCoffLib.h>

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/PeCoffExtraActionLib.h>

+#include <Library/SemihostLib.h>

+#include <Library/PrintLib.h>

+

+/**

+  Append string to debugger script file, create file if needed.

+

+  This library can show up in mulitple places so we need to append the file every time we write to it.

+  For example Sec can use this to load the DXE core, and the DXE core would use this to load all the

+  other modules. So we have two instances of the library in the system.

+

+  @param  Buffer  Buffer to write to file.

+  @param  Length  Length of Buffer in bytes.

+**/

+VOID

+WriteStringToFile (

+  IN  VOID    *Buffer,

+  IN  UINT32  Length

+  )

+{

+  // Working around and issue with the code that is commented out. For now send it to the console.

+  // You can copy the console into a file and source the file as a script and you get symbols.

+  // This gets you all the symbols except for SEC. To get SEC symbols you need to copy the

+  // debug print in the SEC into the debugger manually

+  SemihostWriteString (Buffer);

+/*

+  I'm currently having issues with this code crashing the debugger. Seems like it should work.

+

+  UINT32        SemihostHandle;

+  UINT32        SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;

+

+  SemihostFileOpen ("c:\rvi_symbols.inc", SemihostMode, &SemihostHandle);

+  SemihostFileWrite (SemihostHandle, &Length, Buffer);

+  SemihostFileClose (SemihostHandle);

+ */

+}

+

+

+/**

+  If the build is done on cygwin the paths are cygpaths.

+  /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert

+  them to work with RVD commands

+

+  @param  Name  Path to convert if needed

+

+**/

+CHAR8 *

+DeCygwinPathIfNeeded (

+  IN  CHAR8   *Name

+  )

+{

+  CHAR8   *Ptr;

+  UINTN   Index;

+  UINTN   Len;

+

+  Ptr = AsciiStrStr (Name, "/cygdrive/");

+  if (Ptr == NULL) {

+    return Name;

+  }

+

+  Len = AsciiStrLen (Ptr);

+

+  // convert "/cygdrive" to spaces

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

+    Ptr[Index] = ' ';

+  }

+

+  // convert /c to c:

+  Ptr[9]  = Ptr[10];

+  Ptr[10] = ':';

+

+  // switch path separators

+  for (Index = 11; Index < Len; Index++) {

+    if (Ptr[Index] == '/') {

+      Ptr[Index] = '\\' ;

+    }

+  }

+

+  return Name;

+}

+

+

+/**

+  Performs additional actions after a PE/COFF image has been loaded and relocated.

+

+  If ImageContext is NULL, then ASSERT().

+

+  @param  ImageContext  Pointer to the image context structure that describes the

+                        PE/COFF image that has already been loaded and relocated.

+

+**/

+VOID

+EFIAPI

+PeCoffLoaderRelocateImageExtraAction (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  CHAR8 Buffer[256];

+

+#if (__ARMCC_VERSION < 500000)

+  AsciiSPrint (Buffer, sizeof(Buffer), "load /a /ni /np \"%a\" &0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));

+#else

+  AsciiSPrint (Buffer, sizeof(Buffer), "add-symbol-file %a 0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));

+#endif

+  DeCygwinPathIfNeeded (&Buffer[16]);

+

+  WriteStringToFile (Buffer, AsciiStrSize (Buffer));

+}

+

+

+

+/**

+  Performs additional actions just before a PE/COFF image is unloaded.  Any resources

+  that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.

+

+  If ImageContext is NULL, then ASSERT().

+

+  @param  ImageContext  Pointer to the image context structure that describes the

+                        PE/COFF image that is being unloaded.

+

+**/

+VOID

+EFIAPI

+PeCoffLoaderUnloadImageExtraAction (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  CHAR8 Buffer[256];

+

+  AsciiSPrint (Buffer, sizeof(Buffer), "unload symbols_only \"%a\"\n", ImageContext->PdbPointer);

+  DeCygwinPathIfNeeded (Buffer);

+

+  WriteStringToFile (Buffer, AsciiStrSize (Buffer));

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
new file mode 100644
index 0000000..3be0237
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
@@ -0,0 +1,41 @@
+#/** @file

+# PeCoff extra action libary for DXE phase that run Unix emulator.

+#

+# Lib to provide memory journal status code reporting Routines

+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = RvdUnixPeCoffExtraActionLib

+  FILE_GUID                      = 5EDEB7E7-EA55-4E92-8216-335AC98A3B11

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeCoffExtraActionLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = ARM

+#

+

+[Sources.common]

+  RvdPeCoffExtraActionLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  DebugLib

+  SemihostLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c
new file mode 100644
index 0000000..ec03edb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c
@@ -0,0 +1,246 @@
+/** @file

+  UEFI Debug Library that uses PrintLib to send messages to STDERR.

+

+  Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+

+#include <Uefi.h>

+#include <Library/DebugLib.h>

+#include <Library/PrintLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/SemihostLib.h>

+

+//

+// Define the maximum debug and assert message length that this library supports

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+/**

+

+  Prints a debug message to the debug output device if the specified error level is enabled.

+

+  If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print

+  the message specified by Format and the associated variable argument list to

+  the debug output device.

+

+  If Format is NULL, then ASSERT().

+

+  @param  ErrorLevel  The error level of the debug message.

+  @param  Format      Format string for the debug message to print.

+

+**/

+VOID

+EFIAPI

+DebugPrint (

+  IN  UINTN        ErrorLevel,

+  IN  CONST CHAR8  *Format,

+  ...

+  )

+{

+  CHAR8    AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver debug mask value and global mask

+  //

+  if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {

+    return;

+  }

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  AsciiVSPrint (AsciiBuffer, sizeof (AsciiBuffer), Format, Marker);

+  VA_END (Marker);

+

+  SemihostWriteString (AsciiBuffer);

+}

+

+

+/**

+

+  Prints an assert message containing a filename, line number, and description.

+  This may be followed by a breakpoint or a dead loop.

+

+  Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"

+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of

+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if

+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then

+  CpuDeadLoop() is called.  If neither of these bits are set, then this function

+  returns immediately after the message is printed to the debug output device.

+  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while

+  processing another DebugAssert(), then DebugAssert() must return immediately.

+

+  If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.

+

+  If Description is NULL, then a <Description> string of "(NULL) Description" is printed.

+

+  @param  FileName     Pointer to the name of the source file that generated the assert condition.

+  @param  LineNumber   The line number in the source file that generated the assert condition

+  @param  Description  Pointer to the description of the assert condition.

+

+**/

+VOID

+EFIAPI

+DebugAssert (

+  IN CONST CHAR8  *FileName,

+  IN UINTN        LineNumber,

+  IN CONST CHAR8  *Description

+  )

+{

+  CHAR8   AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  AsciiSPrint (AsciiBuffer, sizeof (AsciiBuffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description);

+

+  SemihostWriteString (AsciiBuffer);

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+

+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.

+

+  This function fills Length bytes of Buffer with the value specified by

+  PcdDebugClearMemoryValue, and returns Buffer.

+

+  If Buffer is NULL, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().

+

+  @param   Buffer  Pointer to the target buffer to fill with PcdDebugClearMemoryValue.

+  @param   Length  Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.

+

+  @return  Buffer

+

+**/

+VOID *

+EFIAPI

+DebugClearMemory (

+  OUT VOID  *Buffer,

+  IN UINTN  Length

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+

+  Returns TRUE if ASSERT() macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugAssertEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**

+

+  Returns TRUE if DEBUG()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugPrintEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**

+

+  Returns TRUE if DEBUG_CODE()macros are enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugCodeEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**

+

+  Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.

+

+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of

+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.

+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+DebugClearMemoryEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
new file mode 100644
index 0000000..4c2c5ff
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
@@ -0,0 +1,47 @@
+

+#/** @file

+# Debug Library for UEFI drivers

+#

+# Library to abstract Framework extensions that conflict with UEFI 2.0 Specification

+# Copyright (c) 2007, Intel Corporation. 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                      = SemiHostingDebugLib

+  FILE_GUID                      = 2A8D3FC4-8DB1-4D27-A3F3-780AF03CF848

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugLib|BASE SEC DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER

+

+

+[Sources.common]

+  DebugLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  BaseMemoryLib

+  BaseLib

+  PcdLib

+  PrintLib

+  SemihostLib

+  DebugLib

+

+[Pcd.common]

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel

+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
new file mode 100644
index 0000000..fedf389
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
@@ -0,0 +1,34 @@
+#/** @file

+# Semihosting  serail port lib

+#

+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SemiHostingSerialPortLib

+  FILE_GUID                      = E9FB2D1E-05D9-421C-8C35-6100BB0093B7

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SerialPortLib

+

+

+[Sources.common]

+  SerialPortLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  SemihostLib

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c
new file mode 100644
index 0000000..bc4d691
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c
@@ -0,0 +1,144 @@
+/** @file

+  Serial I/O Port library functions with no library constructor/destructor

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#include <Uefi.h>

+#include <Library/DebugLib.h>

+#include <Library/SemihostLib.h>

+#include <Library/SerialPortLib.h>

+

+

+/*

+

+  Programmed hardware of Serial port.

+

+  @return    Always return EFI_UNSUPPORTED.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortInitialize (

+  VOID

+  )

+{

+  if (SemihostConnectionSupported ()) {

+    return RETURN_SUCCESS;

+  } else {

+    return RETURN_UNSUPPORTED;

+  }

+}

+

+/**

+  Write data to serial device.

+

+  @param  Buffer           Point of data buffer which need to be writed.

+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.

+

+  @retval 0                Write data failed.

+  @retval !0               Actual number of bytes writed to serial device.

+

+**/

+

+#define PRINT_BUFFER_SIZE       512

+#define PRINT_BUFFER_THRESHOLD  (PRINT_BUFFER_SIZE - 4)

+

+UINTN

+EFIAPI

+SerialPortWrite (

+  IN UINT8     *Buffer,

+  IN UINTN     NumberOfBytes

+)

+{

+  UINT8 PrintBuffer[PRINT_BUFFER_SIZE];

+  UINTN SourceIndex      = 0;

+  UINTN DestinationIndex = 0;

+  UINT8 CurrentCharacter;

+

+  while (SourceIndex < NumberOfBytes)

+  {

+      CurrentCharacter = Buffer[SourceIndex++];

+

+      switch (CurrentCharacter)

+      {

+      case '\r':

+          continue;

+

+      case '\n':

+          PrintBuffer[DestinationIndex++] = ' ';

+          // fall through

+

+      default:

+          PrintBuffer[DestinationIndex++] = CurrentCharacter;

+          break;

+      }

+

+      if (DestinationIndex > PRINT_BUFFER_THRESHOLD)

+      {

+          PrintBuffer[DestinationIndex] = '\0';

+          SemihostWriteString ((CHAR8 *) PrintBuffer);

+

+          DestinationIndex = 0;

+      }

+  }

+

+  if (DestinationIndex > 0)

+  {

+      PrintBuffer[DestinationIndex] = '\0';

+      SemihostWriteString ((CHAR8 *) PrintBuffer);

+  }

+

+  return NumberOfBytes;

+}

+

+

+/**

+  Read data from serial device and save the datas in buffer.

+

+  @param  Buffer           Point of data buffer which need to be writed.

+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.

+

+  @retval 0                Read data failed.

+  @retval !0               Aactual number of bytes read from serial device.

+

+**/

+UINTN

+EFIAPI

+SerialPortRead (

+  OUT UINT8     *Buffer,

+  IN  UINTN     NumberOfBytes

+)

+{

+  *Buffer = SemihostReadCharacter ();

+  return 1;

+}

+

+

+

+/**

+  Check to see if any data is avaiable to be read from the debug device.

+

+  @retval TRUE       At least one byte of data is avaiable to be read

+  @retval FALSE      No data is avaiable to be read

+

+**/

+BOOLEAN

+EFIAPI

+SerialPortPoll (

+  VOID

+  )

+{

+  // Since SemiHosting read character is blocking always say we have a char ready?

+  return SemihostConnectionSupported ();

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
new file mode 100644
index 0000000..42211cf
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
@@ -0,0 +1,23 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+

+.globl ASM_PFX(GccSemihostCall)

+

+ASM_PFX(GccSemihostCall):

+  hlt     #0xf000

+  ret

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
new file mode 100755
index 0000000..c9d1318
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 2

+

+.globl ASM_PFX(GccSemihostCall)

+INTERWORK_FUNC(GccSemihostCall)

+

+/*

+  Semihosting operation request mechanism

+

+  SVC  0x123456  in ARM state (for all architectures)

+  SVC  0xAB in Thumb state (excluding ARMv7-M)

+  BKPT 0xAB for ARMv7-M (Thumb-2 only)

+

+  R0 - operation type

+  R1 - block containing all other parametes

+

+  lr - must be saved as svc instruction will cause an svc exception and write

+       the svc lr register. That happens to be the one we are using, so we must

+       save it or we will not be able to return.

+ */

+ASM_PFX(GccSemihostCall):

+  stmfd   sp!, {lr}

+  svc     #0x123456

+  ldmfd   sp!, {lr}

+  bx      lr

+

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.c b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.c
new file mode 100644
index 0000000..b1bbcbb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.c
@@ -0,0 +1,313 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2013 - 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 <Base.h>

+

+#include <Library/BaseLib.h>

+#include <Library/SemihostLib.h>

+

+#include "SemihostPrivate.h"

+

+BOOLEAN

+SemihostConnectionSupported (

+  VOID

+  )

+{

+  return SEMIHOST_SUPPORTED;

+}

+

+RETURN_STATUS

+SemihostFileOpen (

+  IN  CHAR8  *FileName,

+  IN  UINT32 Mode,

+  OUT UINTN  *FileHandle

+  )

+{

+  SEMIHOST_FILE_OPEN_BLOCK  OpenBlock;

+  INT32                     Result;

+

+  if (FileHandle == NULL) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  // Remove any leading separator (e.g.: '\'). EFI Shell adds one.

+  if (*FileName == '\\') {

+    FileName++;

+  }

+

+  OpenBlock.FileName    = FileName;

+  OpenBlock.Mode        = Mode;

+  OpenBlock.NameLength  = AsciiStrLen(FileName);

+

+  Result = Semihost_SYS_OPEN(&OpenBlock);

+

+  if (Result == -1) {

+    return RETURN_NOT_FOUND;

+  } else {

+    *FileHandle = Result;

+    return RETURN_SUCCESS;

+  }

+}

+

+RETURN_STATUS

+SemihostFileSeek (

+  IN UINTN  FileHandle,

+  IN UINTN  Offset

+  )

+{

+  SEMIHOST_FILE_SEEK_BLOCK  SeekBlock;

+  INT32                     Result;

+

+  SeekBlock.Handle   = FileHandle;

+  SeekBlock.Location = Offset;

+

+  Result = Semihost_SYS_SEEK(&SeekBlock);

+

+  // Semihosting does not behave as documented. It returns the offset on

+  // success.

+  if (Result < 0) {

+    return RETURN_ABORTED;

+  } else {

+    return RETURN_SUCCESS;

+  }

+}

+

+RETURN_STATUS

+SemihostFileRead (

+  IN     UINTN  FileHandle,

+  IN OUT UINTN  *Length,

+  OUT    VOID   *Buffer

+  )

+{

+  SEMIHOST_FILE_READ_WRITE_BLOCK  ReadBlock;

+  UINT32                          Result;

+

+  if ((Length == NULL) || (Buffer == NULL)) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  ReadBlock.Handle = FileHandle;

+  ReadBlock.Buffer = Buffer;

+  ReadBlock.Length = *Length;

+

+  Result = Semihost_SYS_READ(&ReadBlock);

+

+  if ((*Length != 0) && (Result == *Length)) {

+    return RETURN_ABORTED;

+  } else {

+    *Length -= Result;

+    return RETURN_SUCCESS;

+  }

+}

+

+RETURN_STATUS

+SemihostFileWrite (

+  IN     UINTN  FileHandle,

+  IN OUT UINTN  *Length,

+  IN     VOID   *Buffer

+  )

+{

+  SEMIHOST_FILE_READ_WRITE_BLOCK  WriteBlock;

+

+  if ((Length == NULL) || (Buffer == NULL)) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  WriteBlock.Handle = FileHandle;

+  WriteBlock.Buffer = Buffer;

+  WriteBlock.Length = *Length;

+

+  *Length = Semihost_SYS_WRITE(&WriteBlock);

+

+  if (*Length != 0)

+    return RETURN_ABORTED;

+  else

+    return RETURN_SUCCESS;

+}

+

+RETURN_STATUS

+SemihostFileClose (

+  IN UINTN  FileHandle

+  )

+{

+  INT32 Result = Semihost_SYS_CLOSE(&FileHandle);

+

+  if (Result == -1) {

+    return RETURN_INVALID_PARAMETER;

+  } else {

+    return RETURN_SUCCESS;

+  }

+}

+

+RETURN_STATUS

+SemihostFileLength (

+  IN  UINTN  FileHandle,

+  OUT UINTN  *Length

+  )

+{

+  INT32       Result;

+

+  if (Length == NULL) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  Result = Semihost_SYS_FLEN(&FileHandle);

+

+  if (Result == -1) {

+    return RETURN_ABORTED;

+  } else {

+    *Length = Result;

+    return RETURN_SUCCESS;

+  }

+}

+

+/**

+  Get a temporary name for a file from the host running the debug agent.

+

+  @param[out]  Buffer      Pointer to the buffer where the temporary name has to

+                           be stored

+  @param[in]   Identifier  File name identifier (integer in the range 0 to 255)

+  @param[in]   Length      Length of the buffer to store the temporary name

+

+  @retval  RETURN_SUCCESS            Temporary name returned

+  @retval  RETURN_INVALID_PARAMETER  Invalid buffer address

+  @retval  RETURN_ABORTED            Temporary name not returned

+

+**/

+RETURN_STATUS

+SemihostFileTmpName(

+  OUT  VOID   *Buffer,

+  IN   UINT8  Identifier,

+  IN   UINTN  Length

+  )

+{

+  SEMIHOST_FILE_TMPNAME_BLOCK  TmpNameBlock;

+  INT32                        Result;

+

+  if (Buffer == NULL) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  TmpNameBlock.Buffer     = Buffer;

+  TmpNameBlock.Identifier = Identifier;

+  TmpNameBlock.Length     = Length;

+

+  Result = Semihost_SYS_TMPNAME (&TmpNameBlock);

+

+  if (Result != 0) {

+    return  RETURN_ABORTED;

+  } else {

+    return  RETURN_SUCCESS;

+  }

+}

+

+RETURN_STATUS

+SemihostFileRemove (

+  IN CHAR8 *FileName

+  )

+{

+  SEMIHOST_FILE_REMOVE_BLOCK  RemoveBlock;

+  UINT32                      Result;

+

+  // Remove any leading separator (e.g.: '\'). EFI Shell adds one.

+  if (*FileName == '\\') {

+    FileName++;

+  }

+

+  RemoveBlock.FileName    = FileName;

+  RemoveBlock.NameLength  = AsciiStrLen(FileName);

+

+  Result = Semihost_SYS_REMOVE(&RemoveBlock);

+

+  if (Result == 0) {

+    return RETURN_SUCCESS;

+  } else {

+    return RETURN_ABORTED;

+  }

+}

+

+/**

+  Rename a specified file.

+

+  @param[in]  FileName     Name of the file to rename.

+  @param[in]  NewFileName  The new name of the file.

+

+  @retval  RETURN_SUCCESS            File Renamed

+  @retval  RETURN_INVALID_PARAMETER  Either the current or the new name is not specified

+  @retval  RETURN_ABORTED            Rename failed

+

+**/

+RETURN_STATUS

+SemihostFileRename(

+  IN  CHAR8  *FileName,

+  IN  CHAR8  *NewFileName

+  )

+{

+  SEMIHOST_FILE_RENAME_BLOCK  RenameBlock;

+  INT32                       Result;

+

+  if ((FileName == NULL) || (NewFileName == NULL)) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  RenameBlock.FileName          = FileName;

+  RenameBlock.FileNameLength    = AsciiStrLen (FileName);

+  RenameBlock.NewFileName       = NewFileName;

+  RenameBlock.NewFileNameLength = AsciiStrLen (NewFileName);

+

+  Result = Semihost_SYS_RENAME (&RenameBlock);

+

+  if (Result != 0) {

+    return  RETURN_ABORTED;

+  } else {

+    return  RETURN_SUCCESS;

+  }

+}

+

+CHAR8

+SemihostReadCharacter (

+  VOID

+  )

+{

+  return Semihost_SYS_READC();

+}

+

+VOID

+SemihostWriteCharacter (

+  IN CHAR8 Character

+  )

+{

+  Semihost_SYS_WRITEC(&Character);

+}

+

+VOID

+SemihostWriteString (

+  IN CHAR8 *String

+  )

+{

+  Semihost_SYS_WRITE0(String);

+}

+

+UINT32

+SemihostSystem (

+  IN CHAR8 *CommandLine

+  )

+{

+  SEMIHOST_SYSTEM_BLOCK SystemBlock;

+

+  SystemBlock.CommandLine   = CommandLine;

+  SystemBlock.CommandLength = AsciiStrLen(CommandLine);

+

+  return Semihost_SYS_SYSTEM(&SystemBlock);

+}

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.inf b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.inf
new file mode 100644
index 0000000..460f4cd
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.inf
@@ -0,0 +1,46 @@
+#/** @file

+# Semihosting JTAG lib

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+# 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.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SemihostLib

+  FILE_GUID                      = C40D08BA-DB7B-4F07-905A-C5FE4B5AF987

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SemihostLib

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = ARM AARCH64

+#

+[Sources.common]

+  SemihostLib.c

+

+[Sources.ARM]

+  Arm/GccSemihost.S | GCC

+

+[Sources.AARCH64]

+  AArch64/GccSemihost.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  BaseLib

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostPrivate.h b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostPrivate.h
new file mode 100644
index 0000000..afc5327
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostPrivate.h
@@ -0,0 +1,218 @@
+/** @file

+

+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>

+

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef __SEMIHOST_PRIVATE_H__

+#define __SEMIHOST_PRIVATE_H__

+

+typedef struct {

+  CHAR8   *FileName;

+  UINTN    Mode;

+  UINTN    NameLength;

+} SEMIHOST_FILE_OPEN_BLOCK;

+

+typedef struct {

+  UINTN    Handle;

+  VOID    *Buffer;

+  UINTN    Length;

+} SEMIHOST_FILE_READ_WRITE_BLOCK;

+

+typedef struct {

+  UINTN    Handle;

+  UINTN    Location;

+} SEMIHOST_FILE_SEEK_BLOCK;

+

+typedef struct {

+  VOID    *Buffer;

+  UINTN    Identifier;

+  UINTN    Length;

+} SEMIHOST_FILE_TMPNAME_BLOCK;

+

+typedef struct {

+  CHAR8   *FileName;

+  UINTN    NameLength;

+} SEMIHOST_FILE_REMOVE_BLOCK;

+

+typedef struct {

+  CHAR8   *FileName;

+  UINTN    FileNameLength;

+  CHAR8   *NewFileName;

+  UINTN    NewFileNameLength;

+} SEMIHOST_FILE_RENAME_BLOCK;

+

+typedef struct {

+  CHAR8   *CommandLine;

+  UINTN    CommandLength;

+} SEMIHOST_SYSTEM_BLOCK;

+

+#if defined(__CC_ARM)

+

+#if defined(__thumb__)

+#define SWI 0xAB

+#else

+#define SWI 0x123456

+#endif

+

+#define SEMIHOST_SUPPORTED  TRUE

+

+__swi(SWI)

+INT32

+_Semihost_SYS_OPEN(

+  IN UINTN                    SWI_0x01,

+  IN SEMIHOST_FILE_OPEN_BLOCK *OpenBlock

+  );

+

+__swi(SWI)

+INT32

+_Semihost_SYS_CLOSE(

+  IN UINTN  SWI_0x02,

+  IN UINT32 *Handle

+  );

+

+__swi(SWI)

+VOID

+_Semihost_SYS_WRITEC(

+  IN UINTN    SWI_0x03,

+  IN CHAR8    *Character

+  );

+

+__swi(SWI)

+VOID

+_Semihost_SYS_WRITE0(

+  IN UINTN SWI_0x04,

+  IN CHAR8 *String

+  );

+

+__swi(SWI)

+UINT32

+_Semihost_SYS_WRITE(

+  IN     UINTN                          SWI_0x05,

+  IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *WriteBlock

+  );

+

+__swi(SWI)

+UINT32

+_Semihost_SYS_READ(

+  IN     UINTN                          SWI_0x06,

+  IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *ReadBlock

+  );

+

+__swi(SWI)

+CHAR8

+_Semihost_SYS_READC(

+  IN     UINTN SWI_0x07,

+  IN     UINTN Zero

+  );

+

+__swi(SWI)

+INT32

+_Semihost_SYS_SEEK(

+  IN UINTN                    SWI_0x0A,

+  IN SEMIHOST_FILE_SEEK_BLOCK *SeekBlock

+  );

+

+__swi(SWI)

+INT32

+_Semihost_SYS_FLEN(

+  IN UINTN  SWI_0x0C,

+  IN UINT32 *Handle

+  );

+

+__swi(SWI)

+UINT32

+_Semihost_SYS_TMPNAME(

+  IN UINTN                       SWI_0x0D,

+  IN SEMIHOST_FILE_TMPNAME_BLOCK *TmpNameBlock

+  );

+

+__swi(SWI)

+UINT32

+_Semihost_SYS_REMOVE(

+  IN UINTN                      SWI_0x0E,

+  IN SEMIHOST_FILE_REMOVE_BLOCK *RemoveBlock

+  );

+

+__swi(SWI)

+UINT32

+_Semihost_SYS_RENAME(

+  IN UINTN                      SWI_0x0F,

+  IN SEMIHOST_FILE_RENAME_BLOCK *RenameBlock

+  );

+

+__swi(SWI)

+UINT32

+_Semihost_SYS_SYSTEM(

+  IN UINTN                 SWI_0x12,

+  IN SEMIHOST_SYSTEM_BLOCK *SystemBlock

+  );

+

+#define Semihost_SYS_OPEN(OpenBlock)        _Semihost_SYS_OPEN(0x01, OpenBlock)

+#define Semihost_SYS_CLOSE(Handle)          _Semihost_SYS_CLOSE(0x02, Handle)

+#define Semihost_SYS_WRITE0(String)         _Semihost_SYS_WRITE0(0x04, String)

+#define Semihost_SYS_WRITEC(Character)      _Semihost_SYS_WRITEC(0x03, Character)

+#define Semihost_SYS_WRITE(WriteBlock)      _Semihost_SYS_WRITE(0x05, WriteBlock)

+#define Semihost_SYS_READ(ReadBlock)        _Semihost_SYS_READ(0x06, ReadBlock)

+#define Semihost_SYS_READC()                _Semihost_SYS_READC(0x07, 0)

+#define Semihost_SYS_SEEK(SeekBlock)        _Semihost_SYS_SEEK(0x0A, SeekBlock)

+#define Semihost_SYS_FLEN(Handle)           _Semihost_SYS_FLEN(0x0C, Handle)

+#define Semihost_SYS_TMPNAME(TmpNameBlock)  _Semihost_SYS_TMPNAME(0x0D, TmpNameBlock)

+#define Semihost_SYS_REMOVE(RemoveBlock)    _Semihost_SYS_REMOVE(0x0E, RemoveBlock)

+#define Semihost_SYS_RENAME(RenameBlock)    _Semihost_SYS_RENAME(0x0F, RenameBlock)

+#define Semihost_SYS_SYSTEM(SystemBlock)    _Semihost_SYS_SYSTEM(0x12, SystemBlock)

+

+#elif defined(__GNUC__) // __CC_ARM

+

+#define SEMIHOST_SUPPORTED  TRUE

+

+UINT32

+GccSemihostCall (

+  IN UINT32   Operation,

+  IN UINTN    SystemBlockAddress

+  ); // __attribute__ ((interrupt ("SVC")));

+

+#define Semihost_SYS_OPEN(OpenBlock)        GccSemihostCall(0x01, (UINTN)(OpenBlock))

+#define Semihost_SYS_CLOSE(Handle)          GccSemihostCall(0x02, (UINTN)(Handle))

+#define Semihost_SYS_WRITE0(String)         GccSemihostCall(0x04, (UINTN)(String))

+#define Semihost_SYS_WRITEC(Character)      GccSemihostCall(0x03, (UINTN)(Character))

+#define Semihost_SYS_WRITE(WriteBlock)      GccSemihostCall(0x05, (UINTN)(WriteBlock))

+#define Semihost_SYS_READ(ReadBlock)        GccSemihostCall(0x06, (UINTN)(ReadBlock))

+#define Semihost_SYS_READC()                GccSemihostCall(0x07, (UINTN)(0))

+#define Semihost_SYS_SEEK(SeekBlock)        GccSemihostCall(0x0A, (UINTN)(SeekBlock))

+#define Semihost_SYS_FLEN(Handle)           GccSemihostCall(0x0C, (UINTN)(Handle))

+#define Semihost_SYS_TMPNAME(TmpNameBlock)  GccSemihostCall(0x0D, (UINTN)(TmpNameBlock))

+#define Semihost_SYS_REMOVE(RemoveBlock)    GccSemihostCall(0x0E, (UINTN)(RemoveBlock))

+#define Semihost_SYS_RENAME(RenameBlock)    GccSemihostCall(0x0F, (UINTN)(RenameBlock))

+#define Semihost_SYS_SYSTEM(SystemBlock)    GccSemihostCall(0x12, (UINTN)(SystemBlock))

+

+#else // __CC_ARM

+

+#define SEMIHOST_SUPPORTED  FALSE

+

+#define Semihost_SYS_OPEN(OpenBlock)        (-1)

+#define Semihost_SYS_CLOSE(Handle)          (-1)

+#define Semihost_SYS_WRITE0(String)

+#define Semihost_SYS_WRITEC(Character)

+#define Semihost_SYS_WRITE(WriteBlock)      (0)

+#define Semihost_SYS_READ(ReadBlock)        ((ReadBlock)->Length)

+#define Semihost_SYS_READC()                ('x')

+#define Semihost_SYS_SEEK(SeekBlock)        (-1)

+#define Semihost_SYS_FLEN(Handle)           (-1)

+#define Semihost_SYS_TMPNAME(TmpNameBlock)  (-1)

+#define Semihost_SYS_REMOVE(RemoveBlock)    (-1)

+#define Semihost_SYS_RENAME(RenameBlock)    (-1)

+#define Semihost_SYS_SYSTEM(SystemBlock)    (-1)

+

+#endif // __CC_ARM

+

+#endif //__SEMIHOST_PRIVATE_H__

diff --git a/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
new file mode 100644
index 0000000..e70d877
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
@@ -0,0 +1,687 @@
+/** @file

+  UncachedMemoryAllocation lib that uses DXE Service to change cachability for

+  a buffer.

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2014, AMR 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/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UncachedMemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Library/ArmLib.h>

+#include <Library/DxeServicesTableLib.h>

+

+VOID *

+UncachedInternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages

+  );

+

+VOID *

+UncachedInternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  );

+

+

+

+//

+// Assume all of memory has the same cache attributes, unless we do our magic

+//

+UINT64  gAttributes;

+

+typedef struct {

+  EFI_PHYSICAL_ADDRESS  Base;

+  VOID                  *Allocation;

+  UINTN                 Pages;

+  EFI_MEMORY_TYPE       MemoryType;

+  BOOLEAN               Allocated;

+  LIST_ENTRY            Link;

+} FREE_PAGE_NODE;

+

+STATIC LIST_ENTRY  mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);

+// Track the size of the non-allocated buffer in the linked-list

+STATIC UINTN   mFreedBufferSize = 0;

+

+/**

+ * This function firstly checks if the requested allocation can fit into one

+ * of the previously allocated buffer.

+ * If the requested allocation does not fit in the existing pool then

+ * the function makes a new allocation.

+ *

+ * @param MemoryType    Type of memory requested for the new allocation

+ * @param Pages         Number of requested page

+ * @param Alignment     Required alignment

+ * @param Allocation    Address of the newly allocated buffer

+ *

+ * @return EFI_SUCCESS  If the function manage to allocate a buffer

+ * @return !EFI_SUCCESS If the function did not manage to allocate a buffer

+ */

+STATIC

+EFI_STATUS

+AllocatePagesFromList (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages,

+  IN UINTN            Alignment,

+  OUT VOID            **Allocation

+  )

+{

+  EFI_STATUS       Status;

+  LIST_ENTRY      *Link;

+  FREE_PAGE_NODE  *Node;

+  FREE_PAGE_NODE  *NewNode;

+  UINTN            AlignmentMask;

+  EFI_PHYSICAL_ADDRESS Memory;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;

+

+  // Alignment must be a power of two or zero.

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  //

+  // Look in our list for the smallest page that could satisfy the new allocation

+  //

+  NewNode = NULL;

+  for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {

+    Node = BASE_CR (Link, FREE_PAGE_NODE, Link);

+    if ((Node->Allocated == FALSE) && (Node->MemoryType == MemoryType)) {

+      // We have a node that fits our requirements

+      if (((UINTN)Node->Base & (Alignment - 1)) == 0) {

+        // We found a page that matches the page size

+        if (Node->Pages == Pages) {

+          Node->Allocated  = TRUE;

+          Node->Allocation = (VOID*)(UINTN)Node->Base;

+          *Allocation      = Node->Allocation;

+

+          // Update the size of the freed buffer

+          mFreedBufferSize  -= Pages * EFI_PAGE_SIZE;

+          return EFI_SUCCESS;

+        } else if (Node->Pages > Pages) {

+          if (NewNode == NULL) {

+            // It is the first node that could contain our new allocation

+            NewNode = Node;

+          } else if (NewNode->Pages > Node->Pages) {

+            // This node offers a smaller number of page.

+            NewNode = Node;

+          }

+        }

+      }

+    }

+  }

+  // Check if we have found a node that could contain our new allocation

+  if (NewNode != NULL) {

+    NewNode->Allocated = TRUE;

+    Node->Allocation   = (VOID*)(UINTN)Node->Base;

+    *Allocation        = Node->Allocation;

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Otherwise, we need to allocate a new buffer

+  //

+

+  // We do not want to over-allocate in case the alignment requirement does not

+  // require extra pages

+  if (Alignment > EFI_PAGE_SIZE) {

+    AlignmentMask  = Alignment - 1;

+    Pages          += EFI_SIZE_TO_PAGES (Alignment);

+  } else {

+    AlignmentMask  = 0;

+  }

+

+  Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = gDS->GetMemorySpaceDescriptor (Memory, &Descriptor);

+  if (!EFI_ERROR (Status)) {

+    // We are making an assumption that all of memory has the same default attributes

+    gAttributes = Descriptor.Attributes;

+  } else {

+    gBS->FreePages (Memory, Pages);

+    return Status;

+  }

+

+  Status = gDS->SetMemorySpaceAttributes (Memory, EFI_PAGES_TO_SIZE (Pages), EFI_MEMORY_WC);

+  if (EFI_ERROR (Status)) {

+    gBS->FreePages (Memory, Pages);

+    return Status;

+  }

+

+  NewNode = AllocatePool (sizeof (FREE_PAGE_NODE));

+  if (NewNode == NULL) {

+    ASSERT (FALSE);

+    gBS->FreePages (Memory, Pages);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  NewNode->Base       = Memory;

+  NewNode->Allocation = (VOID*)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask);

+  NewNode->Pages      = Pages;

+  NewNode->Allocated  = TRUE;

+  NewNode->MemoryType = MemoryType;

+

+  InsertTailList (&mPageList, &NewNode->Link);

+

+  *Allocation = NewNode->Allocation;

+  return EFI_SUCCESS;

+}

+

+/**

+ * Free the memory allocation

+ *

+ * This function will actually try to find the allocation in the linked list.

+ * And it will then mark the entry as freed.

+ *

+ * @param  Allocation  Base address of the buffer to free

+ *

+ * @return EFI_SUCCESS            The allocation has been freed

+ * @return EFI_NOT_FOUND          The allocation was not found in the pool.

+ * @return EFI_INVALID_PARAMETER  If Allocation is NULL

+ *

+ */

+STATIC

+EFI_STATUS

+FreePagesFromList (

+  IN  VOID  *Allocation

+  )

+{

+  LIST_ENTRY      *Link;

+  FREE_PAGE_NODE  *Node;

+

+  if (Allocation == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {

+    Node = BASE_CR (Link, FREE_PAGE_NODE, Link);

+    if ((UINTN)Node->Allocation == (UINTN)Allocation) {

+      Node->Allocated = FALSE;

+

+      // Update the size of the freed buffer

+      mFreedBufferSize  += Node->Pages * EFI_PAGE_SIZE;

+

+      // If the size of the non-allocated reaches the threshold we raise a warning.

+      // It might be an expected behaviour in some cases.

+      // We might device to free some of these buffers later on.

+      if (mFreedBufferSize > PcdGet64 (PcdArmFreeUncachedMemorySizeThreshold)) {

+        DEBUG ((EFI_D_WARN, "Warning: The list of non-allocated buffer has reach the threshold.\n"));

+      }

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+/**

+ * This function is automatically invoked when the driver exits

+ * It frees all the non-allocated memory buffer.

+ * This function is not responsible to free allocated buffer (eg: case of memory leak,

+ * runtime allocation).

+ */

+EFI_STATUS

+EFIAPI

+UncachedMemoryAllocationLibDestructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  LIST_ENTRY      *Link;

+  FREE_PAGE_NODE  *OldNode;

+

+  // Test if the list is empty

+  Link = mPageList.ForwardLink;

+  if (Link == &mPageList) {

+    return EFI_SUCCESS;

+  }

+

+  // Free all the pages and nodes

+  do {

+    OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);

+    // Point to the next entry

+    Link = Link->ForwardLink;

+

+    // We only free the non-allocated buffer

+    if (OldNode->Allocated == FALSE) {

+      gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)OldNode->Base, OldNode->Pages);

+      RemoveEntryList (&OldNode->Link);

+      FreePool (OldNode);

+    }

+  } while (Link != &mPageList);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Converts a cached or uncached address to a physical address suitable for use in SoC registers.

+

+  @param  VirtualAddress                 The pointer to convert.

+

+  @return The physical address of the supplied virtual pointer.

+

+**/

+EFI_PHYSICAL_ADDRESS

+ConvertToPhysicalAddress (

+  IN VOID *VirtualAddress

+  )

+{

+  return (EFI_PHYSICAL_ADDRESS)(UINTN)VirtualAddress;

+}

+

+

+VOID *

+UncachedInternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages

+  )

+{

+  return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);

+}

+

+

+VOID *

+EFIAPI

+UncachedAllocatePages (

+  IN UINTN  Pages

+  )

+{

+  return UncachedInternalAllocatePages (EfiBootServicesData, Pages);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimePages (

+  IN UINTN  Pages

+  )

+{

+  return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedPages (

+  IN UINTN  Pages

+  )

+{

+  return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);

+}

+

+

+

+VOID

+EFIAPI

+UncachedFreePages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  UncachedFreeAlignedPages (Buffer, Pages);

+  return;

+}

+

+

+VOID *

+UncachedInternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  EFI_STATUS Status;

+  VOID   *Allocation;

+

+  if (Pages == 0) {

+    return NULL;

+  }

+

+  Allocation = NULL;

+  Status = AllocatePagesFromList (MemoryType, Pages, Alignment, &Allocation);

+  if (EFI_ERROR (Status)) {

+    ASSERT_EFI_ERROR (Status);

+    return NULL;

+  } else {

+    return Allocation;

+  }

+}

+

+

+VOID

+EFIAPI

+UncachedFreeAlignedPages (

+  IN VOID   *Buffer,

+  IN UINTN  Pages

+  )

+{

+  FreePagesFromList (Buffer);

+}

+

+

+VOID *

+UncachedInternalAllocateAlignedPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID      *AlignedAddress;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  if (Alignment < EFI_PAGE_SIZE) {

+    Alignment = EFI_PAGE_SIZE;

+  }

+

+  AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);

+  if (AlignedAddress == NULL) {

+    return NULL;

+  }

+

+  return (VOID *) AlignedAddress;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimePool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+VOID *

+UncachedInternalAllocateAlignedZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN UINTN            Alignment

+  )

+{

+  VOID    *Memory;

+  Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimeZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedZeroPool (

+  IN UINTN  AllocationSize,

+  IN UINTN  Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);

+}

+

+VOID *

+UncachedInternalAllocateAlignedCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer,

+  IN UINTN            Alignment

+  )

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);

+  if (Memory != NULL) {

+    Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateAlignedReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer,

+  IN UINTN       Alignment

+  )

+{

+  return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);

+}

+

+VOID

+EFIAPI

+UncachedFreeAlignedPool (

+  IN VOID   *Allocation

+  )

+{

+  UncachedFreePages (Allocation, 0);

+}

+

+VOID *

+UncachedInternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,

+  IN UINTN            AllocationSize

+  )

+{

+  UINTN CacheLineLength = ArmDataCacheLineLength ();

+  return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);

+}

+

+VOID *

+EFIAPI

+UncachedAllocatePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimePool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);

+}

+

+VOID *

+UncachedInternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize

+  )

+{

+  VOID  *Memory;

+

+  Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimeZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedZeroPool (

+  IN UINTN  AllocationSize

+  )

+{

+  return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);

+}

+

+VOID *

+UncachedInternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  )

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+VOID *

+EFIAPI

+UncachedAllocateCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateRuntimeCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);

+}

+

+VOID *

+EFIAPI

+UncachedAllocateReservedCopyPool (

+  IN UINTN       AllocationSize,

+  IN CONST VOID  *Buffer

+  )

+{

+  return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);

+}

+

+VOID

+EFIAPI

+UncachedFreePool (

+  IN VOID   *Buffer

+  )

+{

+  UncachedFreeAlignedPool (Buffer);

+}

+

+VOID

+EFIAPI

+UncachedSafeFreePool (

+  IN VOID   *Buffer

+  )

+{

+  if (Buffer != NULL) {

+    UncachedFreePool (Buffer);

+    Buffer = NULL;

+  }

+}

+

diff --git a/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
new file mode 100644
index 0000000..0a0b6cb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
@@ -0,0 +1,43 @@
+#/** @file

+#

+#  UncachedMemoryAllocation lib that uses DXE Service to change cachability for

+#  a buffer.

+#

+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UncachedMemoryAllocationLib

+  FILE_GUID                      = DC101A1A-7525-429B-84AF-EEAA630E576C

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UncachedMemoryAllocationLib

+

+  DESTRUCTOR                     = UncachedMemoryAllocationLibDestructor

+

+[Sources.common]

+  UncachedMemoryAllocationLib.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  ArmLib

+  MemoryAllocationLib

+  PcdLib

+  DxeServicesTableLib

+

+[Pcd]

+  gArmTokenSpaceGuid.PcdArmFreeUncachedMemorySizeThreshold

diff --git a/uefi/linaro-edk2/ArmPkg/License.txt b/uefi/linaro-edk2/ArmPkg/License.txt
new file mode 100755
index 0000000..05dbd36
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/License.txt
@@ -0,0 +1,26 @@
+Copyright (c) 2009-2010, Apple Inc. All rights reserved.

+Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+

+Redistribution and use in source and binary forms, with or without

+modification, are permitted provided that the following conditions

+are met:

+

+* Redistributions of source code must retain the above copyright

+  notice, this list of conditions and the following disclaimer.

+* Redistributions in binary form must reproduce the above copyright

+  notice, this list of conditions and the following disclaimer in

+  the documentation and/or other materials provided with the

+  distribution.

+

+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,

+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER

+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN

+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

+POSSIBILITY OF SUCH DAMAGE.